overleaf/services/web/test/UnitTests/coffee/Authorization/AuthorizationMiddlewearTests.coffee
2017-10-13 11:20:57 +01:00

247 lines
8.7 KiB
CoffeeScript

sinon = require('sinon')
chai = require('chai')
should = chai.should()
expect = chai.expect
modulePath = "../../../../app/js/Features/Authorization/AuthorizationMiddlewear.js"
SandboxedModule = require('sandboxed-module')
Errors = require "../../../../app/js/Features/Errors/Errors.js"
describe "AuthorizationMiddlewear", ->
beforeEach ->
@user_id = "user-id-123"
@project_id = "project-id-123"
@token = 'some-token'
@AuthenticationController =
getLoggedInUserId: sinon.stub().returns(@user_id)
isUserLoggedIn: sinon.stub().returns(true)
@AuthorizationMiddlewear = SandboxedModule.require modulePath, requires:
"./AuthorizationManager": @AuthorizationManager = {}
"logger-sharelatex": {log: () ->}
"mongojs": ObjectId: @ObjectId = {}
"../Errors/Errors": Errors
'../Authentication/AuthenticationController': @AuthenticationController
"../TokenAccess/TokenAccessHandler": @TokenAccessHandler =
getRequestToken: sinon.stub().returns(@token)
@req = {}
@res = {}
@ObjectId.isValid = sinon.stub()
@ObjectId.isValid.withArgs(@project_id).returns true
@next = sinon.stub()
METHODS_TO_TEST = {
"ensureUserCanReadProject": "canUserReadProject"
"ensureUserCanWriteProjectSettings": "canUserWriteProjectSettings"
"ensureUserCanWriteProjectContent": "canUserWriteProjectContent"
"ensureUserCanAdminProject": "canUserAdminProject"
}
for middlewearMethod, managerMethod of METHODS_TO_TEST
do (middlewearMethod, managerMethod) ->
describe middlewearMethod, ->
beforeEach ->
@req.params =
project_id: @project_id
@AuthorizationManager[managerMethod] = sinon.stub()
@AuthorizationMiddlewear.redirectToRestricted = sinon.stub()
describe "with missing project_id", ->
beforeEach ->
@req.params = {}
it "should return an error to next", ->
@AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
@next.calledWith(new Error()).should.equal true
describe "with logged in user", ->
beforeEach ->
@AuthenticationController.getLoggedInUserId.returns(@user_id)
describe "when user has permission", ->
beforeEach ->
@AuthorizationManager[managerMethod]
.withArgs(@user_id, @project_id, @token)
.yields(null, true)
it "should return next", ->
@AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
@next.called.should.equal true
describe "when user doesn't have permission", ->
beforeEach ->
@AuthorizationManager[managerMethod]
.withArgs(@user_id, @project_id, @token)
.yields(null, false)
it "should redirect to redirectToRestricted", ->
@AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
@next.called.should.equal false
@AuthorizationMiddlewear.redirectToRestricted
.calledWith(@req, @res, @next)
.should.equal true
describe "with anonymous user", ->
describe "when user has permission", ->
beforeEach ->
@AuthenticationController.getLoggedInUserId.returns(null)
@AuthorizationManager[managerMethod]
.withArgs(null, @project_id, @token)
.yields(null, true)
it "should return next", ->
@AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
@next.called.should.equal true
describe "when user doesn't have permission", ->
beforeEach ->
@AuthenticationController.getLoggedInUserId.returns(null)
@AuthorizationManager[managerMethod]
.withArgs(null, @project_id, @token)
.yields(null, false)
it "should redirect to redirectToRestricted", ->
@AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
@next.called.should.equal false
@AuthorizationMiddlewear.redirectToRestricted
.calledWith(@req, @res, @next)
.should.equal true
describe "with malformed project id", ->
beforeEach ->
@req.params =
project_id: "blah"
@ObjectId.isValid = sinon.stub().returns false
it "should return a not found error", (done) ->
@AuthorizationMiddlewear[middlewearMethod] @req, @res, (error) ->
error.should.be.instanceof Errors.NotFoundError
done()
describe "ensureUserIsSiteAdmin", ->
beforeEach ->
@AuthorizationManager.isUserSiteAdmin = sinon.stub()
@AuthorizationMiddlewear.redirectToRestricted = sinon.stub()
describe "with logged in user", ->
beforeEach ->
@AuthenticationController.getLoggedInUserId.returns(@user_id)
describe "when user has permission", ->
beforeEach ->
@AuthorizationManager.isUserSiteAdmin
.withArgs(@user_id)
.yields(null, true)
it "should return next", ->
@AuthorizationMiddlewear.ensureUserIsSiteAdmin @req, @res, @next
@next.called.should.equal true
describe "when user doesn't have permission", ->
beforeEach ->
@AuthorizationManager.isUserSiteAdmin
.withArgs(@user_id)
.yields(null, false)
it "should redirect to redirectToRestricted", ->
@AuthorizationMiddlewear.ensureUserIsSiteAdmin @req, @res, @next
@next.called.should.equal false
@AuthorizationMiddlewear.redirectToRestricted
.calledWith(@req, @res, @next)
.should.equal true
describe "with anonymous user", ->
describe "when user has permission", ->
beforeEach ->
@AuthenticationController.getLoggedInUserId.returns(null)
@AuthorizationManager.isUserSiteAdmin
.withArgs(null)
.yields(null, true)
it "should return next", ->
@AuthorizationMiddlewear.ensureUserIsSiteAdmin @req, @res, @next
@next.called.should.equal true
describe "when user doesn't have permission", ->
beforeEach ->
@AuthenticationController.getLoggedInUserId.returns(null)
@AuthorizationManager.isUserSiteAdmin
.withArgs(null)
.yields(null, false)
it "should redirect to redirectToRestricted", ->
@AuthorizationMiddlewear.ensureUserIsSiteAdmin @req, @res, @next
@next.called.should.equal false
@AuthorizationMiddlewear.redirectToRestricted
.calledWith(@req, @res, @next)
.should.equal true
describe "ensureUserCanReadMultipleProjects", ->
beforeEach ->
@AuthorizationManager.canUserReadProject = sinon.stub()
@AuthorizationMiddlewear.redirectToRestricted = sinon.stub()
@req.query =
project_ids: "project1,project2"
describe "with logged in user", ->
beforeEach ->
@AuthenticationController.getLoggedInUserId.returns(@user_id)
describe "when user has permission to access all projects", ->
beforeEach ->
@AuthorizationManager.canUserReadProject
.withArgs(@user_id, "project1", @token)
.yields(null, true)
@AuthorizationManager.canUserReadProject
.withArgs(@user_id, "project2", @token)
.yields(null, true)
it "should return next", ->
@AuthorizationMiddlewear.ensureUserCanReadMultipleProjects @req, @res, @next
@next.called.should.equal true
describe "when user doesn't have permission to access one of the projects", ->
beforeEach ->
@AuthorizationManager.canUserReadProject
.withArgs(@user_id, "project1", @token)
.yields(null, true)
@AuthorizationManager.canUserReadProject
.withArgs(@user_id, "project2", @token)
.yields(null, false)
it "should redirect to redirectToRestricted", ->
@AuthorizationMiddlewear.ensureUserCanReadMultipleProjects @req, @res, @next
@next.called.should.equal false
@AuthorizationMiddlewear.redirectToRestricted
.calledWith(@req, @res, @next)
.should.equal true
describe "with anonymous user", ->
describe "when user has permission", ->
describe "when user has permission to access all projects", ->
beforeEach ->
@AuthenticationController.getLoggedInUserId.returns(null)
@AuthorizationManager.canUserReadProject
.withArgs(null, "project1", @token)
.yields(null, true)
@AuthorizationManager.canUserReadProject
.withArgs(null, "project2", @token)
.yields(null, true)
it "should return next", ->
@AuthorizationMiddlewear.ensureUserCanReadMultipleProjects @req, @res, @next
@next.called.should.equal true
describe "when user doesn't have permission to access one of the projects", ->
beforeEach ->
@AuthenticationController.getLoggedInUserId.returns(null)
@AuthorizationManager.canUserReadProject
.withArgs(null, "project1", @token)
.yields(null, true)
@AuthorizationManager.canUserReadProject
.withArgs(null, "project2", @token)
.yields(null, false)
it "should redirect to redirectToRestricted", ->
@AuthorizationMiddlewear.ensureUserCanReadMultipleProjects @req, @res, @next
@next.called.should.equal false
@AuthorizationMiddlewear.redirectToRestricted
.calledWith(@req, @res, @next)
.should.equal true