overleaf/services/web/test/unit/coffee/Authorization/AuthorizationMiddlewearTests.coffee

275 lines
9.6 KiB
CoffeeScript
Raw Normal View History

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 ->
2016-09-07 11:40:49 -04:00
@user_id = "user-id-123"
@project_id = "project-id-123"
@token = 'some-token'
2016-09-07 11:40:49 -04:00
@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
2016-09-07 11:40:49 -04:00
'../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()
2016-09-07 11:40:49 -04:00
describe "_getUserId", ->
beforeEach ->
@req = {}
it "should get the user from session", (done) ->
@AuthenticationController.getLoggedInUserId = sinon.stub().returns("1234")
@AuthorizationMiddlewear._getUserId @req, (err, user_id) =>
expect(err).to.not.exist
expect(user_id).to.equal "1234"
done()
it "should get oauth_user from request", (done) ->
@AuthenticationController.getLoggedInUserId = sinon.stub().returns(null)
@req.oauth_user = {_id: "5678"}
@AuthorizationMiddlewear._getUserId @req, (err, user_id) =>
expect(err).to.not.exist
expect(user_id).to.equal "5678"
done()
it "should fall back to null", (done) ->
@AuthenticationController.getLoggedInUserId = sinon.stub().returns(null)
@req.oauth_user = undefined
@AuthorizationMiddlewear._getUserId @req, (err, user_id) =>
expect(err).to.not.exist
expect(user_id).to.equal null
done()
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()
2016-09-07 11:40:49 -04:00
describe "with missing project_id", ->
beforeEach ->
@req.params = {}
2016-09-07 11:40:49 -04:00
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 ->
2016-09-07 11:40:49 -04:00
@AuthenticationController.getLoggedInUserId.returns(@user_id)
describe "when user has permission", ->
beforeEach ->
@AuthorizationManager[managerMethod]
.withArgs(@user_id, @project_id, @token)
.yields(null, true)
2016-09-07 11:40:49 -04:00
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)
2016-09-07 11:40:49 -04:00
it "should redirect to redirectToRestricted", ->
@AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
@next.called.should.equal false
@AuthorizationMiddlewear.redirectToRestricted
.calledWith(@req, @res, @next)
.should.equal true
2016-09-07 11:40:49 -04:00
describe "with anonymous user", ->
describe "when user has permission", ->
beforeEach ->
2016-09-07 11:40:49 -04:00
@AuthenticationController.getLoggedInUserId.returns(null)
@AuthorizationManager[managerMethod]
.withArgs(null, @project_id, @token)
.yields(null, true)
2016-09-07 11:40:49 -04:00
it "should return next", ->
@AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
@next.called.should.equal true
describe "when user doesn't have permission", ->
beforeEach ->
2016-09-07 11:40:49 -04:00
@AuthenticationController.getLoggedInUserId.returns(null)
@AuthorizationManager[managerMethod]
.withArgs(null, @project_id, @token)
.yields(null, false)
2016-09-07 11:40:49 -04:00
it "should redirect to redirectToRestricted", ->
@AuthorizationMiddlewear[middlewearMethod] @req, @res, @next
@next.called.should.equal false
@AuthorizationMiddlewear.redirectToRestricted
.calledWith(@req, @res, @next)
.should.equal true
2016-09-07 11:40:49 -04:00
describe "with malformed project id", ->
beforeEach ->
@req.params =
project_id: "blah"
@ObjectId.isValid = sinon.stub().returns false
2016-09-07 11:40:49 -04:00
it "should return a not found error", (done) ->
@AuthorizationMiddlewear[middlewearMethod] @req, @res, (error) ->
error.should.be.instanceof Errors.NotFoundError
done()
2016-09-07 11:40:49 -04:00
describe "ensureUserIsSiteAdmin", ->
beforeEach ->
@AuthorizationManager.isUserSiteAdmin = sinon.stub()
@AuthorizationMiddlewear.redirectToRestricted = sinon.stub()
describe "with logged in user", ->
beforeEach ->
2016-09-07 11:40:49 -04:00
@AuthenticationController.getLoggedInUserId.returns(@user_id)
describe "when user has permission", ->
beforeEach ->
@AuthorizationManager.isUserSiteAdmin
.withArgs(@user_id)
.yields(null, true)
2016-09-07 11:40:49 -04:00
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)
2016-09-07 11:40:49 -04:00
it "should redirect to redirectToRestricted", ->
@AuthorizationMiddlewear.ensureUserIsSiteAdmin @req, @res, @next
@next.called.should.equal false
@AuthorizationMiddlewear.redirectToRestricted
.calledWith(@req, @res, @next)
.should.equal true
2016-09-07 11:40:49 -04:00
describe "with anonymous user", ->
describe "when user has permission", ->
beforeEach ->
2016-09-07 11:40:49 -04:00
@AuthenticationController.getLoggedInUserId.returns(null)
@AuthorizationManager.isUserSiteAdmin
.withArgs(null)
.yields(null, true)
2016-09-07 11:40:49 -04:00
it "should return next", ->
@AuthorizationMiddlewear.ensureUserIsSiteAdmin @req, @res, @next
@next.called.should.equal true
describe "when user doesn't have permission", ->
beforeEach ->
2016-09-07 11:40:49 -04:00
@AuthenticationController.getLoggedInUserId.returns(null)
@AuthorizationManager.isUserSiteAdmin
.withArgs(null)
.yields(null, false)
2016-09-07 11:40:49 -04:00
it "should redirect to redirectToRestricted", ->
@AuthorizationMiddlewear.ensureUserIsSiteAdmin @req, @res, @next
@next.called.should.equal false
@AuthorizationMiddlewear.redirectToRestricted
.calledWith(@req, @res, @next)
.should.equal true
2016-09-07 11:40:49 -04:00
describe "ensureUserCanReadMultipleProjects", ->
beforeEach ->
@AuthorizationManager.canUserReadProject = sinon.stub()
@AuthorizationMiddlewear.redirectToRestricted = sinon.stub()
@req.query =
project_ids: "project1,project2"
2016-09-07 11:40:49 -04:00
describe "with logged in user", ->
beforeEach ->
2016-09-07 11:40:49 -04:00
@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)
2016-09-07 11:40:49 -04:00
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)
2016-09-07 11:40:49 -04:00
it "should redirect to redirectToRestricted", ->
@AuthorizationMiddlewear.ensureUserCanReadMultipleProjects @req, @res, @next
@next.called.should.equal false
@AuthorizationMiddlewear.redirectToRestricted
.calledWith(@req, @res, @next)
.should.equal true
2016-09-07 11:40:49 -04:00
describe "with anonymous user", ->
describe "when user has permission", ->
describe "when user has permission to access all projects", ->
beforeEach ->
2016-09-07 11:40:49 -04:00
@AuthenticationController.getLoggedInUserId.returns(null)
@AuthorizationManager.canUserReadProject
.withArgs(null, "project1", @token)
.yields(null, true)
@AuthorizationManager.canUserReadProject
.withArgs(null, "project2", @token)
.yields(null, true)
2016-09-07 11:40:49 -04:00
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 ->
2016-09-07 11:40:49 -04:00
@AuthenticationController.getLoggedInUserId.returns(null)
@AuthorizationManager.canUserReadProject
.withArgs(null, "project1", @token)
.yields(null, true)
@AuthorizationManager.canUserReadProject
.withArgs(null, "project2", @token)
.yields(null, false)
2016-09-07 11:40:49 -04:00
it "should redirect to redirectToRestricted", ->
@AuthorizationMiddlewear.ensureUserCanReadMultipleProjects @req, @res, @next
@next.called.should.equal false
@AuthorizationMiddlewear.redirectToRestricted
.calledWith(@req, @res, @next)
.should.equal true