2019-05-29 05:21:06 -04:00
|
|
|
const sinon = require('sinon')
|
2019-09-30 09:21:49 -04:00
|
|
|
const { expect } = require('chai')
|
2019-05-29 05:21:06 -04:00
|
|
|
const SandboxedModule = require('sandboxed-module')
|
|
|
|
const Errors = require('../../../../app/src/Features/Errors/Errors.js')
|
|
|
|
|
2019-09-30 09:21:49 -04:00
|
|
|
const MODULE_PATH =
|
|
|
|
'../../../../app/src/Features/Authorization/AuthorizationMiddleware.js'
|
|
|
|
|
2019-05-29 05:21:06 -04:00
|
|
|
describe('AuthorizationMiddleware', function() {
|
|
|
|
beforeEach(function() {
|
2019-09-30 09:21:49 -04:00
|
|
|
this.userId = 'user-id-123'
|
2019-05-29 05:21:06 -04:00
|
|
|
this.project_id = 'project-id-123'
|
|
|
|
this.token = 'some-token'
|
|
|
|
this.AuthenticationController = {
|
2019-09-30 09:21:49 -04:00
|
|
|
getLoggedInUserId: sinon.stub().returns(this.userId),
|
2019-05-29 05:21:06 -04:00
|
|
|
isUserLoggedIn: sinon.stub().returns(true)
|
|
|
|
}
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager = {}
|
2020-07-09 09:47:43 -04:00
|
|
|
this.HttpErrorHandler = {
|
|
|
|
forbidden: sinon.stub()
|
|
|
|
}
|
2019-09-30 09:21:49 -04:00
|
|
|
this.TokenAccessHandler = {
|
|
|
|
getRequestToken: sinon.stub().returns(this.token)
|
|
|
|
}
|
|
|
|
this.ObjectId = {
|
|
|
|
isValid: sinon
|
|
|
|
.stub()
|
|
|
|
.withArgs(this.project_id)
|
|
|
|
.returns(true)
|
|
|
|
}
|
|
|
|
this.AuthorizationManager = {}
|
|
|
|
this.AuthorizationMiddleware = SandboxedModule.require(MODULE_PATH, {
|
2019-07-15 06:33:47 -04:00
|
|
|
globals: {
|
|
|
|
console: console
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
requires: {
|
2019-09-30 09:21:49 -04:00
|
|
|
'./AuthorizationManager': this.AuthorizationManager,
|
2019-05-29 05:21:06 -04:00
|
|
|
'logger-sharelatex': { log() {} },
|
|
|
|
mongojs: {
|
2019-09-30 09:21:49 -04:00
|
|
|
ObjectId: this.ObjectId
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
2020-07-09 09:47:43 -04:00
|
|
|
'../Errors/HttpErrorHandler': this.HttpErrorHandler,
|
2019-05-29 05:21:06 -04:00
|
|
|
'../Errors/Errors': Errors,
|
|
|
|
'../Authentication/AuthenticationController': this
|
|
|
|
.AuthenticationController,
|
2019-09-30 09:21:49 -04:00
|
|
|
'../TokenAccess/TokenAccessHandler': this.TokenAccessHandler
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
})
|
|
|
|
this.req = {}
|
|
|
|
this.res = {}
|
2019-09-30 09:21:49 -04:00
|
|
|
this.next = sinon.stub()
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('_getUserId', function() {
|
|
|
|
beforeEach(function() {
|
2019-09-30 09:21:49 -04:00
|
|
|
this.req = {}
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should get the user from session', function(done) {
|
|
|
|
this.AuthenticationController.getLoggedInUserId = sinon
|
|
|
|
.stub()
|
|
|
|
.returns('1234')
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware._getUserId(this.req, (err, userId) => {
|
|
|
|
expect(err).to.not.exist
|
|
|
|
expect(userId).to.equal('1234')
|
|
|
|
done()
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should get oauth_user from request', function(done) {
|
|
|
|
this.AuthenticationController.getLoggedInUserId = sinon
|
|
|
|
.stub()
|
|
|
|
.returns(null)
|
|
|
|
this.req.oauth_user = { _id: '5678' }
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware._getUserId(this.req, (err, userId) => {
|
|
|
|
expect(err).to.not.exist
|
|
|
|
expect(userId).to.equal('5678')
|
|
|
|
done()
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should fall back to null', function(done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthenticationController.getLoggedInUserId = sinon
|
|
|
|
.stub()
|
|
|
|
.returns(null)
|
|
|
|
this.req.oauth_user = undefined
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware._getUserId(this.req, (err, userId) => {
|
|
|
|
expect(err).to.not.exist
|
|
|
|
expect(userId).to.equal(null)
|
|
|
|
done()
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
const METHODS_TO_TEST = {
|
|
|
|
ensureUserCanReadProject: 'canUserReadProject',
|
|
|
|
ensureUserCanWriteProjectSettings: 'canUserWriteProjectSettings',
|
2019-09-30 09:21:49 -04:00
|
|
|
ensureUserCanWriteProjectContent: 'canUserWriteProjectContent'
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2019-09-30 09:21:49 -04:00
|
|
|
Object.entries(METHODS_TO_TEST).forEach(
|
|
|
|
([middlewareMethod, managerMethod]) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
describe(middlewareMethod, function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.req.params = { project_id: this.project_id }
|
|
|
|
this.AuthorizationManager[managerMethod] = sinon.stub()
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware.redirectToRestricted = sinon.stub()
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('with missing project_id', function() {
|
|
|
|
beforeEach(function() {
|
2019-09-30 09:21:49 -04:00
|
|
|
this.req.params = {}
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should return an error to next', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware[middlewareMethod](
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
2019-11-18 09:37:05 -05:00
|
|
|
this.next
|
|
|
|
.calledWith(sinon.match.instanceOf(Error))
|
|
|
|
.should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('with logged in user', function() {
|
|
|
|
beforeEach(function() {
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthenticationController.getLoggedInUserId.returns(this.userId)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('when user has permission', function() {
|
|
|
|
beforeEach(function() {
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager[managerMethod]
|
|
|
|
.withArgs(this.userId, this.project_id, this.token)
|
2019-05-29 05:21:06 -04:00
|
|
|
.yields(null, true)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should return next', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware[middlewareMethod](
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.next.called.should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
describe("when user doesn't have permission", function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
beforeEach(function() {
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager[managerMethod]
|
|
|
|
.withArgs(this.userId, this.project_id, this.token)
|
2019-05-29 05:21:06 -04:00
|
|
|
.yields(null, false)
|
|
|
|
})
|
|
|
|
|
2019-09-30 09:21:49 -04:00
|
|
|
it('should raise a 403', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware[middlewareMethod](
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
this.next.called.should.equal(false)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware.redirectToRestricted
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.req, this.res, this.next)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('with anonymous user', function() {
|
|
|
|
describe('when user has permission', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthenticationController.getLoggedInUserId.returns(null)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager[managerMethod]
|
2019-05-29 05:21:06 -04:00
|
|
|
.withArgs(null, this.project_id, this.token)
|
|
|
|
.yields(null, true)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should return next', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware[middlewareMethod](
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.next.called.should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
describe("when user doesn't have permission", function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthenticationController.getLoggedInUserId.returns(null)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager[managerMethod]
|
2019-05-29 05:21:06 -04:00
|
|
|
.withArgs(null, this.project_id, this.token)
|
|
|
|
.yields(null, false)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should redirect to redirectToRestricted', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware[middlewareMethod](
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
this.next.called.should.equal(false)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware.redirectToRestricted
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.req, this.res, this.next)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
describe('with malformed project id', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
beforeEach(function() {
|
|
|
|
this.req.params = { project_id: 'blah' }
|
2019-09-30 09:21:49 -04:00
|
|
|
this.ObjectId.isValid = sinon.stub().returns(false)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should return a not found error', function(done) {
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware[middlewareMethod](
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req,
|
|
|
|
this.res,
|
2019-08-07 10:04:04 -04:00
|
|
|
error => {
|
2019-05-29 05:21:06 -04:00
|
|
|
error.should.be.instanceof(Errors.NotFoundError)
|
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
2019-09-30 09:21:49 -04:00
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
describe('ensureUserCanAdminProject', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.req.params = { project_id: this.project_id }
|
|
|
|
this.AuthorizationManager.canUserAdminProject = sinon.stub()
|
|
|
|
this.AuthorizationMiddleware.redirectToRestricted = sinon.stub()
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('with missing project_id', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.req.params = {}
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return an error to next', function() {
|
|
|
|
this.AuthorizationMiddleware.ensureUserCanAdminProject(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
2019-11-18 09:37:05 -05:00
|
|
|
this.next.calledWith(sinon.match.instanceOf(Error)).should.equal(true)
|
2019-09-30 09:21:49 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('with logged in user', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthenticationController.getLoggedInUserId.returns(this.userId)
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('when user has permission', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthorizationManager.canUserAdminProject
|
|
|
|
.withArgs(this.userId, this.project_id, this.token)
|
|
|
|
.yields(null, true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return next', function() {
|
|
|
|
this.AuthorizationMiddleware.ensureUserCanAdminProject(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
this.next.called.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe("when user doesn't have permission", function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthorizationManager.canUserAdminProject
|
|
|
|
.withArgs(this.userId, this.project_id, this.token)
|
|
|
|
.yields(null, false)
|
|
|
|
})
|
|
|
|
|
2020-07-09 09:47:43 -04:00
|
|
|
it('should invoke HTTP forbidden error handler', function(done) {
|
|
|
|
this.HttpErrorHandler.forbidden = sinon.spy(() => done())
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware.ensureUserCanAdminProject(
|
|
|
|
this.req,
|
2020-07-09 09:47:43 -04:00
|
|
|
this.res
|
2019-09-30 09:21:49 -04:00
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('with anonymous user', function() {
|
|
|
|
describe('when user has permission', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthenticationController.getLoggedInUserId.returns(null)
|
|
|
|
this.AuthorizationManager.canUserAdminProject
|
|
|
|
.withArgs(null, this.project_id, this.token)
|
|
|
|
.yields(null, true)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return next', function() {
|
|
|
|
this.AuthorizationMiddleware.ensureUserCanAdminProject(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
this.next.called.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe("when user doesn't have permission", function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthenticationController.getLoggedInUserId.returns(null)
|
|
|
|
this.AuthorizationManager.canUserAdminProject
|
|
|
|
.withArgs(null, this.project_id, this.token)
|
|
|
|
.yields(null, false)
|
|
|
|
})
|
|
|
|
|
2020-07-09 09:47:43 -04:00
|
|
|
it('should invoke HTTP forbidden error handler', function(done) {
|
|
|
|
this.HttpErrorHandler.forbidden = sinon.spy(() => done())
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware.ensureUserCanAdminProject(
|
|
|
|
this.req,
|
2020-07-09 09:47:43 -04:00
|
|
|
this.res
|
2019-09-30 09:21:49 -04:00
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('with malformed project id', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.req.params = { project_id: 'blah' }
|
|
|
|
this.ObjectId.isValid = sinon.stub().returns(false)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return a not found error', function(done) {
|
|
|
|
this.AuthorizationMiddleware.ensureUserCanAdminProject(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
error => {
|
|
|
|
error.should.be.instanceof(Errors.NotFoundError)
|
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
|
|
|
describe('ensureUserIsSiteAdmin', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthorizationManager.isUserSiteAdmin = sinon.stub()
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware.redirectToRestricted = sinon.stub()
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('with logged in user', function() {
|
|
|
|
beforeEach(function() {
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthenticationController.getLoggedInUserId.returns(this.userId)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('when user has permission', function() {
|
|
|
|
beforeEach(function() {
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager.isUserSiteAdmin
|
|
|
|
.withArgs(this.userId)
|
2019-05-29 05:21:06 -04:00
|
|
|
.yields(null, true)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should return next', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware.ensureUserIsSiteAdmin(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.next.called.should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
describe("when user doesn't have permission", function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
beforeEach(function() {
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager.isUserSiteAdmin
|
|
|
|
.withArgs(this.userId)
|
2019-05-29 05:21:06 -04:00
|
|
|
.yields(null, false)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should redirect to redirectToRestricted', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware.ensureUserIsSiteAdmin(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
this.next.called.should.equal(false)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware.redirectToRestricted
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.req, this.res, this.next)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
describe('with anonymous user', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
describe('when user has permission', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthenticationController.getLoggedInUserId.returns(null)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager.isUserSiteAdmin
|
2019-05-29 05:21:06 -04:00
|
|
|
.withArgs(null)
|
|
|
|
.yields(null, true)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should return next', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware.ensureUserIsSiteAdmin(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.next.called.should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
describe("when user doesn't have permission", function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthenticationController.getLoggedInUserId.returns(null)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager.isUserSiteAdmin
|
2019-05-29 05:21:06 -04:00
|
|
|
.withArgs(null)
|
|
|
|
.yields(null, false)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should redirect to redirectToRestricted', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware.ensureUserIsSiteAdmin(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
this.next.called.should.equal(false)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware.redirectToRestricted
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.req, this.res, this.next)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2020-06-04 04:47:12 -04:00
|
|
|
describe('blockRestrictedUserFromProject', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthorizationMiddleware._getUserAndProjectId = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, this.userId, this.project_id)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should issue a 401 response for a restricted user', function(done) {
|
|
|
|
this.AuthorizationManager.isRestrictedUserForProject = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(3, null, true)
|
|
|
|
this.req = {}
|
|
|
|
this.next = sinon.stub()
|
|
|
|
this.res.sendStatus = status => {
|
|
|
|
expect(status).to.equal(403)
|
|
|
|
expect(
|
|
|
|
this.AuthorizationManager.isRestrictedUserForProject.called
|
|
|
|
).to.equal(true)
|
|
|
|
expect(this.next.called).to.equal(false)
|
|
|
|
done()
|
|
|
|
}
|
|
|
|
this.AuthorizationMiddleware.blockRestrictedUserFromProject(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should pass through for a regular user', function(done) {
|
|
|
|
this.AuthorizationManager.isRestrictedUserForProject = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(3, null, false)
|
|
|
|
this.req = {}
|
|
|
|
this.res.sendStatus = sinon.stub()
|
|
|
|
this.next = status => {
|
|
|
|
expect(
|
|
|
|
this.AuthorizationManager.isRestrictedUserForProject.called
|
|
|
|
).to.equal(true)
|
|
|
|
expect(this.res.sendStatus.called).to.equal(false)
|
|
|
|
done()
|
|
|
|
}
|
|
|
|
this.AuthorizationMiddleware.blockRestrictedUserFromProject(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
describe('ensureUserCanReadMultipleProjects', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthorizationManager.canUserReadProject = sinon.stub()
|
|
|
|
this.AuthorizationMiddleware.redirectToRestricted = sinon.stub()
|
2019-09-30 09:21:49 -04:00
|
|
|
this.req.query = { project_ids: 'project1,project2' }
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('with logged in user', function() {
|
|
|
|
beforeEach(function() {
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthenticationController.getLoggedInUserId.returns(this.userId)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('when user has permission to access all projects', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthorizationManager.canUserReadProject
|
2019-09-30 09:21:49 -04:00
|
|
|
.withArgs(this.userId, 'project1', this.token)
|
2019-05-29 05:21:06 -04:00
|
|
|
.yields(null, true)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager.canUserReadProject
|
|
|
|
.withArgs(this.userId, 'project2', this.token)
|
2019-05-29 05:21:06 -04:00
|
|
|
.yields(null, true)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should return next', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware.ensureUserCanReadMultipleProjects(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.next.called.should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
describe("when user doesn't have permission to access one of the projects", function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthorizationManager.canUserReadProject
|
2019-09-30 09:21:49 -04:00
|
|
|
.withArgs(this.userId, 'project1', this.token)
|
2019-05-29 05:21:06 -04:00
|
|
|
.yields(null, true)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager.canUserReadProject
|
|
|
|
.withArgs(this.userId, 'project2', this.token)
|
2019-05-29 05:21:06 -04:00
|
|
|
.yields(null, false)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should redirect to redirectToRestricted', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware.ensureUserCanReadMultipleProjects(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
this.next.called.should.equal(false)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware.redirectToRestricted
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.req, this.res, this.next)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-08-07 10:04:04 -04:00
|
|
|
describe('with anonymous user', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
describe('when user has permission', function() {
|
|
|
|
describe('when user has permission to access all projects', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthenticationController.getLoggedInUserId.returns(null)
|
|
|
|
this.AuthorizationManager.canUserReadProject
|
|
|
|
.withArgs(null, 'project1', this.token)
|
|
|
|
.yields(null, true)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager.canUserReadProject
|
2019-05-29 05:21:06 -04:00
|
|
|
.withArgs(null, 'project2', this.token)
|
|
|
|
.yields(null, true)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should return next', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware.ensureUserCanReadMultipleProjects(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.next.called.should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
describe("when user doesn't have permission to access one of the projects", function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
beforeEach(function() {
|
|
|
|
this.AuthenticationController.getLoggedInUserId.returns(null)
|
|
|
|
this.AuthorizationManager.canUserReadProject
|
|
|
|
.withArgs(null, 'project1', this.token)
|
|
|
|
.yields(null, true)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationManager.canUserReadProject
|
2019-05-29 05:21:06 -04:00
|
|
|
.withArgs(null, 'project2', this.token)
|
|
|
|
.yields(null, false)
|
|
|
|
})
|
|
|
|
|
2019-06-21 09:46:09 -04:00
|
|
|
it('should redirect to redirectToRestricted', function() {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.AuthorizationMiddleware.ensureUserCanReadMultipleProjects(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
this.next.called.should.equal(false)
|
2019-09-30 09:21:49 -04:00
|
|
|
this.AuthorizationMiddleware.redirectToRestricted
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(this.req, this.res, this.next)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
2019-08-07 10:04:04 -04:00
|
|
|
})
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|