|
@@ -1,47 +1,62 @@
|
|
|
-/* eslint-disable
|
|
|
|
|
- node/handle-callback-err,
|
|
|
|
|
- max-len,
|
|
|
|
|
- no-return-assign,
|
|
|
|
|
- no-unused-vars,
|
|
|
|
|
-*/
|
|
|
|
|
-// TODO: This file was created by bulk-decaffeinate.
|
|
|
|
|
-// Fix any style issues and re-enable lint.
|
|
|
|
|
-/*
|
|
|
|
|
- * decaffeinate suggestions:
|
|
|
|
|
- * DS102: Remove unnecessary code created because of implicit returns
|
|
|
|
|
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
|
|
|
- */
|
|
|
|
|
const sinon = require('sinon')
|
|
const sinon = require('sinon')
|
|
|
const { expect } = require('chai')
|
|
const { expect } = require('chai')
|
|
|
const modulePath =
|
|
const modulePath =
|
|
|
'../../../../app/src/Features/Authorization/AuthorizationManager.js'
|
|
'../../../../app/src/Features/Authorization/AuthorizationManager.js'
|
|
|
const SandboxedModule = require('sandboxed-module')
|
|
const SandboxedModule = require('sandboxed-module')
|
|
|
-const Errors = require('../../../../app/src/Features/Errors/Errors.js')
|
|
|
|
|
|
|
+const Errors = require('../../../../app/src/Features/Errors/Errors')
|
|
|
|
|
+const PrivilegeLevels = require('../../../../app/src/Features/Authorization/PrivilegeLevels')
|
|
|
|
|
+const PublicAccessLevels = require('../../../../app/src/Features/Authorization/PublicAccessLevels')
|
|
|
const { ObjectId } = require('mongodb')
|
|
const { ObjectId } = require('mongodb')
|
|
|
|
|
|
|
|
describe('AuthorizationManager', function () {
|
|
describe('AuthorizationManager', function () {
|
|
|
beforeEach(function () {
|
|
beforeEach(function () {
|
|
|
|
|
+ this.user = { _id: new ObjectId() }
|
|
|
|
|
+ this.project = { _id: new ObjectId() }
|
|
|
|
|
+ this.token = 'some-token'
|
|
|
|
|
+
|
|
|
|
|
+ this.ProjectGetter = {
|
|
|
|
|
+ promises: {
|
|
|
|
|
+ getProject: sinon.stub().resolves(null),
|
|
|
|
|
+ },
|
|
|
|
|
+ }
|
|
|
|
|
+ this.ProjectGetter.promises.getProject
|
|
|
|
|
+ .withArgs(this.project._id)
|
|
|
|
|
+ .resolves(this.project)
|
|
|
|
|
+
|
|
|
|
|
+ this.CollaboratorsGetter = {
|
|
|
|
|
+ promises: {
|
|
|
|
|
+ getMemberIdPrivilegeLevel: sinon.stub().resolves(PrivilegeLevels.NONE),
|
|
|
|
|
+ },
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.CollaboratorsHandler = {}
|
|
|
|
|
+
|
|
|
|
|
+ this.User = {
|
|
|
|
|
+ findOne: sinon.stub().returns({ exec: sinon.stub().resolves(null) }),
|
|
|
|
|
+ }
|
|
|
|
|
+ this.User.findOne
|
|
|
|
|
+ .withArgs({ _id: this.user._id })
|
|
|
|
|
+ .returns({ exec: sinon.stub().resolves(this.user) })
|
|
|
|
|
+
|
|
|
|
|
+ this.TokenAccessHandler = {
|
|
|
|
|
+ promises: {
|
|
|
|
|
+ validateTokenForAnonymousAccess: sinon
|
|
|
|
|
+ .stub()
|
|
|
|
|
+ .resolves({ isValidReadAndWrite: false, isValidReadOnly: false }),
|
|
|
|
|
+ },
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
this.AuthorizationManager = SandboxedModule.require(modulePath, {
|
|
this.AuthorizationManager = SandboxedModule.require(modulePath, {
|
|
|
requires: {
|
|
requires: {
|
|
|
mongodb: { ObjectId },
|
|
mongodb: { ObjectId },
|
|
|
- '../Collaborators/CollaboratorsGetter': (this.CollaboratorsGetter = {}),
|
|
|
|
|
- '../Collaborators/CollaboratorsHandler': (this.CollaboratorsHandler = {}),
|
|
|
|
|
- '../Project/ProjectGetter': (this.ProjectGetter = {}),
|
|
|
|
|
- '../../models/User': {
|
|
|
|
|
- User: (this.User = {}),
|
|
|
|
|
- },
|
|
|
|
|
- '../TokenAccess/TokenAccessHandler': (this.TokenAccessHandler = {
|
|
|
|
|
- validateTokenForAnonymousAccess: sinon
|
|
|
|
|
- .stub()
|
|
|
|
|
- .callsArgWith(2, null, false, false),
|
|
|
|
|
- }),
|
|
|
|
|
|
|
+ '../Collaborators/CollaboratorsGetter': this.CollaboratorsGetter,
|
|
|
|
|
+ '../Collaborators/CollaboratorsHandler': this.CollaboratorsHandler,
|
|
|
|
|
+ '../Project/ProjectGetter': this.ProjectGetter,
|
|
|
|
|
+ '../../models/User': { User: this.User },
|
|
|
|
|
+ '../TokenAccess/TokenAccessHandler': this.TokenAccessHandler,
|
|
|
'@overleaf/settings': { passwordStrengthOptions: {} },
|
|
'@overleaf/settings': { passwordStrengthOptions: {} },
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
|
- this.user_id = 'user-id-1'
|
|
|
|
|
- this.project_id = 'project-id-1'
|
|
|
|
|
- this.token = 'some-token'
|
|
|
|
|
- return (this.callback = sinon.stub())
|
|
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('isRestrictedUser', function () {
|
|
describe('isRestrictedUser', function () {
|
|
@@ -59,12 +74,12 @@ describe('AuthorizationManager', function () {
|
|
|
['id', false, true],
|
|
['id', false, true],
|
|
|
['id', false, false],
|
|
['id', false, false],
|
|
|
]
|
|
]
|
|
|
- for (var notRestrictedArgs of notRestrictedScenarios) {
|
|
|
|
|
|
|
+ for (const notRestrictedArgs of notRestrictedScenarios) {
|
|
|
expect(
|
|
expect(
|
|
|
this.AuthorizationManager.isRestrictedUser(...notRestrictedArgs)
|
|
this.AuthorizationManager.isRestrictedUser(...notRestrictedArgs)
|
|
|
).to.equal(false)
|
|
).to.equal(false)
|
|
|
}
|
|
}
|
|
|
- for (var restrictedArgs of restrictedScenarios) {
|
|
|
|
|
|
|
+ for (const restrictedArgs of restrictedScenarios) {
|
|
|
expect(
|
|
expect(
|
|
|
this.AuthorizationManager.isRestrictedUser(...restrictedArgs)
|
|
this.AuthorizationManager.isRestrictedUser(...restrictedArgs)
|
|
|
).to.equal(true)
|
|
).to.equal(true)
|
|
@@ -73,203 +88,144 @@ describe('AuthorizationManager', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('getPrivilegeLevelForProject', function () {
|
|
describe('getPrivilegeLevelForProject', function () {
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.ProjectGetter.getProject = sinon.stub()
|
|
|
|
|
- this.AuthorizationManager.isUserSiteAdmin = sinon.stub()
|
|
|
|
|
- return (this.CollaboratorsGetter.getMemberIdPrivilegeLevel = sinon.stub())
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
describe('with a token-based project', function () {
|
|
describe('with a token-based project', function () {
|
|
|
beforeEach(function () {
|
|
beforeEach(function () {
|
|
|
- return this.ProjectGetter.getProject
|
|
|
|
|
- .withArgs(this.project_id, { publicAccesLevel: 1 })
|
|
|
|
|
- .yields(null, { publicAccesLevel: 'tokenBased' })
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- describe('with a user_id with a privilege level', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.AuthorizationManager.isUserSiteAdmin
|
|
|
|
|
- .withArgs(this.user_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- this.CollaboratorsGetter.getMemberIdPrivilegeLevel
|
|
|
|
|
- .withArgs(this.user_id, this.project_id)
|
|
|
|
|
- .yields(null, 'readOnly')
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ this.project.publicAccesLevel = 'tokenBased'
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ describe('with a user id with a privilege level', function () {
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.CollaboratorsGetter.promises.getMemberIdPrivilegeLevel
|
|
|
|
|
+ .withArgs(this.user._id, this.project._id)
|
|
|
|
|
+ .resolves(PrivilegeLevels.READ_ONLY)
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
|
|
+ this.user._id,
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it("should return the user's privilege level", function () {
|
|
it("should return the user's privilege level", function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, 'readOnly', false, false)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal('readOnly')
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- describe('with a user_id with no privilege level', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.AuthorizationManager.isUserSiteAdmin
|
|
|
|
|
- .withArgs(this.user_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- this.CollaboratorsGetter.getMemberIdPrivilegeLevel
|
|
|
|
|
- .withArgs(this.user_id, this.project_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ describe('with a user id with no privilege level', function () {
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
|
|
+ this.user._id,
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should return false', function () {
|
|
it('should return false', function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, false, false, false)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal(false)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- describe('with a user_id who is an admin', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.AuthorizationManager.isUserSiteAdmin
|
|
|
|
|
- .withArgs(this.user_id)
|
|
|
|
|
- .yields(null, true)
|
|
|
|
|
- this.CollaboratorsGetter.getMemberIdPrivilegeLevel
|
|
|
|
|
- .withArgs(this.user_id, this.project_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ describe('with a user id who is an admin', function () {
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.user.isAdmin = true
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
|
|
+ this.user._id,
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should return the user as an owner', function () {
|
|
it('should return the user as an owner', function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, 'owner', false, true)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal('owner')
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('with no user (anonymous)', function () {
|
|
describe('with no user (anonymous)', function () {
|
|
|
describe('when the token is not valid', function () {
|
|
describe('when the token is not valid', function () {
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.TokenAccessHandler.validateTokenForAnonymousAccess = sinon
|
|
|
|
|
- .stub()
|
|
|
|
|
- .withArgs(this.project_id, this.token)
|
|
|
|
|
- .yields(null, false, false)
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
null,
|
|
null,
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should not call CollaboratorsGetter.getMemberIdPrivilegeLevel', function () {
|
|
it('should not call CollaboratorsGetter.getMemberIdPrivilegeLevel', function () {
|
|
|
- return this.CollaboratorsGetter.getMemberIdPrivilegeLevel.called.should.equal(
|
|
|
|
|
- false
|
|
|
|
|
- )
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should not call AuthorizationManager.isUserSiteAdmin', function () {
|
|
|
|
|
- return this.AuthorizationManager.isUserSiteAdmin.called.should.equal(
|
|
|
|
|
|
|
+ this.CollaboratorsGetter.promises.getMemberIdPrivilegeLevel.called.should.equal(
|
|
|
false
|
|
false
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should check if the token is valid', function () {
|
|
it('should check if the token is valid', function () {
|
|
|
- return this.TokenAccessHandler.validateTokenForAnonymousAccess
|
|
|
|
|
- .calledWith(this.project_id, this.token)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ this.TokenAccessHandler.promises.validateTokenForAnonymousAccess.should.have.been.calledWith(
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
|
|
+ )
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should return false', function () {
|
|
it('should return false', function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, false, false, false)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal(false)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('when the token is valid for read-and-write', function () {
|
|
describe('when the token is valid for read-and-write', function () {
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.TokenAccessHandler.validateTokenForAnonymousAccess = sinon
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.TokenAccessHandler.promises.validateTokenForAnonymousAccess = sinon
|
|
|
.stub()
|
|
.stub()
|
|
|
- .withArgs(this.project_id, this.token)
|
|
|
|
|
- .yields(null, true, false)
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
|
|
+ .withArgs(this.project._id, this.token)
|
|
|
|
|
+ .resolves({ isValidReadAndWrite: true, isValidReadOnly: false })
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
null,
|
|
null,
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should not call CollaboratorsGetter.getMemberIdPrivilegeLevel', function () {
|
|
it('should not call CollaboratorsGetter.getMemberIdPrivilegeLevel', function () {
|
|
|
- return this.CollaboratorsGetter.getMemberIdPrivilegeLevel.called.should.equal(
|
|
|
|
|
- false
|
|
|
|
|
- )
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should not call AuthorizationManager.isUserSiteAdmin', function () {
|
|
|
|
|
- return this.AuthorizationManager.isUserSiteAdmin.called.should.equal(
|
|
|
|
|
|
|
+ this.CollaboratorsGetter.promises.getMemberIdPrivilegeLevel.called.should.equal(
|
|
|
false
|
|
false
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should check if the token is valid', function () {
|
|
it('should check if the token is valid', function () {
|
|
|
- return this.TokenAccessHandler.validateTokenForAnonymousAccess
|
|
|
|
|
- .calledWith(this.project_id, this.token)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ this.TokenAccessHandler.promises.validateTokenForAnonymousAccess.should.have.been.calledWith(
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
|
|
+ )
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should give read-write access', function () {
|
|
it('should give read-write access', function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, 'readAndWrite', false)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal('readAndWrite')
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('when the token is valid for read-only', function () {
|
|
describe('when the token is valid for read-only', function () {
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.TokenAccessHandler.validateTokenForAnonymousAccess = sinon
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.TokenAccessHandler.promises.validateTokenForAnonymousAccess = sinon
|
|
|
.stub()
|
|
.stub()
|
|
|
- .withArgs(this.project_id, this.token)
|
|
|
|
|
- .yields(null, false, true)
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
|
|
+ .withArgs(this.project._id, this.token)
|
|
|
|
|
+ .resolves({ isValidReadAndWrite: false, isValidReadOnly: true })
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
null,
|
|
null,
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should not call CollaboratorsGetter.getMemberIdPrivilegeLevel', function () {
|
|
it('should not call CollaboratorsGetter.getMemberIdPrivilegeLevel', function () {
|
|
|
- return this.CollaboratorsGetter.getMemberIdPrivilegeLevel.called.should.equal(
|
|
|
|
|
- false
|
|
|
|
|
- )
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should not call AuthorizationManager.isUserSiteAdmin', function () {
|
|
|
|
|
- return this.AuthorizationManager.isUserSiteAdmin.called.should.equal(
|
|
|
|
|
|
|
+ this.CollaboratorsGetter.promises.getMemberIdPrivilegeLevel.called.should.equal(
|
|
|
false
|
|
false
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should check if the token is valid', function () {
|
|
it('should check if the token is valid', function () {
|
|
|
- return this.TokenAccessHandler.validateTokenForAnonymousAccess
|
|
|
|
|
- .calledWith(this.project_id, this.token)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ this.TokenAccessHandler.promises.validateTokenForAnonymousAccess.should.have.been.calledWith(
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
|
|
+ )
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should give read-only access', function () {
|
|
it('should give read-only access', function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, 'readOnly', false)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal('readOnly')
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
@@ -277,692 +233,372 @@ describe('AuthorizationManager', function () {
|
|
|
|
|
|
|
|
describe('with a private project', function () {
|
|
describe('with a private project', function () {
|
|
|
beforeEach(function () {
|
|
beforeEach(function () {
|
|
|
- return this.ProjectGetter.getProject
|
|
|
|
|
- .withArgs(this.project_id, { publicAccesLevel: 1 })
|
|
|
|
|
- .yields(null, { publicAccesLevel: 'private' })
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- describe('with a user_id with a privilege level', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.AuthorizationManager.isUserSiteAdmin
|
|
|
|
|
- .withArgs(this.user_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- this.CollaboratorsGetter.getMemberIdPrivilegeLevel
|
|
|
|
|
- .withArgs(this.user_id, this.project_id)
|
|
|
|
|
- .yields(null, 'readOnly')
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ this.project.publicAccesLevel = 'private'
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ describe('with a user id with a privilege level', function () {
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.CollaboratorsGetter.promises.getMemberIdPrivilegeLevel
|
|
|
|
|
+ .withArgs(this.user._id, this.project._id)
|
|
|
|
|
+ .resolves(PrivilegeLevels.READ_ONLY)
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
|
|
+ this.user._id,
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it("should return the user's privilege level", function () {
|
|
it("should return the user's privilege level", function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, 'readOnly', false, false)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal('readOnly')
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- describe('with a user_id with no privilege level', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.AuthorizationManager.isUserSiteAdmin
|
|
|
|
|
- .withArgs(this.user_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- this.CollaboratorsGetter.getMemberIdPrivilegeLevel
|
|
|
|
|
- .withArgs(this.user_id, this.project_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ describe('with a user id with no privilege level', function () {
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
|
|
+ this.user._id,
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should return false', function () {
|
|
it('should return false', function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, false, false, false)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal(false)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- describe('with a user_id who is an admin', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.AuthorizationManager.isUserSiteAdmin
|
|
|
|
|
- .withArgs(this.user_id)
|
|
|
|
|
- .yields(null, true)
|
|
|
|
|
- this.CollaboratorsGetter.getMemberIdPrivilegeLevel
|
|
|
|
|
- .withArgs(this.user_id, this.project_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ describe('with a user id who is an admin', function () {
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.user.isAdmin = true
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
|
|
+ this.user._id,
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should return the user as an owner', function () {
|
|
it('should return the user as an owner', function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, 'owner', false, true)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal('owner')
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('with no user (anonymous)', function () {
|
|
describe('with no user (anonymous)', function () {
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
null,
|
|
null,
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should not call CollaboratorsGetter.getMemberIdPrivilegeLevel', function () {
|
|
it('should not call CollaboratorsGetter.getMemberIdPrivilegeLevel', function () {
|
|
|
- return this.CollaboratorsGetter.getMemberIdPrivilegeLevel.called.should.equal(
|
|
|
|
|
- false
|
|
|
|
|
- )
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should not call AuthorizationManager.isUserSiteAdmin', function () {
|
|
|
|
|
- return this.AuthorizationManager.isUserSiteAdmin.called.should.equal(
|
|
|
|
|
|
|
+ this.CollaboratorsGetter.promises.getMemberIdPrivilegeLevel.called.should.equal(
|
|
|
false
|
|
false
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should return false', function () {
|
|
it('should return false', function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, false, false, false)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal(false)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('with a public project', function () {
|
|
describe('with a public project', function () {
|
|
|
beforeEach(function () {
|
|
beforeEach(function () {
|
|
|
- return this.ProjectGetter.getProject
|
|
|
|
|
- .withArgs(this.project_id, { publicAccesLevel: 1 })
|
|
|
|
|
- .yields(null, { publicAccesLevel: 'readAndWrite' })
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- describe('with a user_id with a privilege level', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.AuthorizationManager.isUserSiteAdmin
|
|
|
|
|
- .withArgs(this.user_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- this.CollaboratorsGetter.getMemberIdPrivilegeLevel
|
|
|
|
|
- .withArgs(this.user_id, this.project_id)
|
|
|
|
|
- .yields(null, 'readOnly')
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ this.project.publicAccesLevel = 'readAndWrite'
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ describe('with a user id with a privilege level', function () {
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.CollaboratorsGetter.promises.getMemberIdPrivilegeLevel
|
|
|
|
|
+ .withArgs(this.user._id, this.project._id)
|
|
|
|
|
+ .resolves(PrivilegeLevels.READ_ONLY)
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
|
|
+ this.user._id,
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it("should return the user's privilege level", function () {
|
|
it("should return the user's privilege level", function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, 'readOnly', false)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal('readOnly')
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- describe('with a user_id with no privilege level', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.AuthorizationManager.isUserSiteAdmin
|
|
|
|
|
- .withArgs(this.user_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- this.CollaboratorsGetter.getMemberIdPrivilegeLevel
|
|
|
|
|
- .withArgs(this.user_id, this.project_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ describe('with a user id with no privilege level', function () {
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
|
|
+ this.user._id,
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should return the public privilege level', function () {
|
|
it('should return the public privilege level', function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, 'readAndWrite', true)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal('readAndWrite')
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- describe('with a user_id who is an admin', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.AuthorizationManager.isUserSiteAdmin
|
|
|
|
|
- .withArgs(this.user_id)
|
|
|
|
|
- .yields(null, true)
|
|
|
|
|
- this.CollaboratorsGetter.getMemberIdPrivilegeLevel
|
|
|
|
|
- .withArgs(this.user_id, this.project_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ describe('with a user id who is an admin', function () {
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.user.isAdmin = true
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
|
|
+ this.user._id,
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should return the user as an owner', function () {
|
|
it('should return the user as an owner', function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, 'owner', false)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal('owner')
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('with no user (anonymous)', function () {
|
|
describe('with no user (anonymous)', function () {
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.result = await this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
null,
|
|
null,
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- this.callback
|
|
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should not call CollaboratorsGetter.getMemberIdPrivilegeLevel', function () {
|
|
it('should not call CollaboratorsGetter.getMemberIdPrivilegeLevel', function () {
|
|
|
- return this.CollaboratorsGetter.getMemberIdPrivilegeLevel.called.should.equal(
|
|
|
|
|
- false
|
|
|
|
|
- )
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should not call AuthorizationManager.isUserSiteAdmin', function () {
|
|
|
|
|
- return this.AuthorizationManager.isUserSiteAdmin.called.should.equal(
|
|
|
|
|
|
|
+ this.CollaboratorsGetter.promises.getMemberIdPrivilegeLevel.called.should.equal(
|
|
|
false
|
|
false
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should return the public privilege level', function () {
|
|
it('should return the public privilege level', function () {
|
|
|
- return this.callback
|
|
|
|
|
- .calledWith(null, 'readAndWrite', true)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
|
|
+ expect(this.result).to.equal('readAndWrite')
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe("when the project doesn't exist", function () {
|
|
describe("when the project doesn't exist", function () {
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.ProjectGetter.getProject
|
|
|
|
|
- .withArgs(this.project_id, { publicAccesLevel: 1 })
|
|
|
|
|
- .yields(null, null)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return a NotFoundError', function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- error => error.should.be.instanceof(Errors.NotFoundError)
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ it('should return a NotFoundError', async function () {
|
|
|
|
|
+ const someOtherId = new ObjectId()
|
|
|
|
|
+ await expect(
|
|
|
|
|
+ this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
|
|
+ this.user._id,
|
|
|
|
|
+ someOtherId,
|
|
|
|
|
+ this.token
|
|
|
|
|
+ )
|
|
|
|
|
+ ).to.be.rejectedWith(Errors.NotFoundError)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('when the project id is not valid', function () {
|
|
describe('when the project id is not valid', function () {
|
|
|
beforeEach(function () {
|
|
beforeEach(function () {
|
|
|
- this.AuthorizationManager.isUserSiteAdmin
|
|
|
|
|
- .withArgs(this.user_id)
|
|
|
|
|
- .yields(null, false)
|
|
|
|
|
- return this.CollaboratorsGetter.getMemberIdPrivilegeLevel
|
|
|
|
|
- .withArgs(this.user_id, this.project_id)
|
|
|
|
|
- .yields(null, 'readOnly')
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return a error', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject(
|
|
|
|
|
- undefined,
|
|
|
|
|
- 'not project id',
|
|
|
|
|
- this.token,
|
|
|
|
|
- err => {
|
|
|
|
|
- this.ProjectGetter.getProject.called.should.equal(false)
|
|
|
|
|
- expect(err).to.exist
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ this.CollaboratorsGetter.promises.getMemberIdPrivilegeLevel
|
|
|
|
|
+ .withArgs(this.user._id, this.project._id)
|
|
|
|
|
+ .resolves(PrivilegeLevels.READ_ONLY)
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- describe('canUserReadProject', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return (this.AuthorizationManager.getPrivilegeLevelForProject = sinon.stub())
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- describe('when user is owner', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'owner', false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return true', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserReadProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canRead) => {
|
|
|
|
|
- expect(canRead).to.equal(true)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ it('should return a error', async function () {
|
|
|
|
|
+ await expect(
|
|
|
|
|
+ this.AuthorizationManager.promises.getPrivilegeLevelForProject(
|
|
|
|
|
+ undefined,
|
|
|
|
|
+ 'not project id',
|
|
|
|
|
+ this.token
|
|
|
|
|
+ )
|
|
|
|
|
+ ).to.be.rejected
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- describe('when user has read-write access', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'readAndWrite', false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return true', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserReadProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canRead) => {
|
|
|
|
|
- expect(canRead).to.equal(true)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ testPermission('canUserReadProject', {
|
|
|
|
|
+ siteAdmin: true,
|
|
|
|
|
+ owner: true,
|
|
|
|
|
+ readAndWrite: true,
|
|
|
|
|
+ readOnly: true,
|
|
|
|
|
+ publicReadAndWrite: true,
|
|
|
|
|
+ publicReadOnly: true,
|
|
|
|
|
+ tokenReadAndWrite: true,
|
|
|
|
|
+ tokenReadOnly: true,
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- describe('when user has read-only access', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'readOnly', false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return true', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserReadProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canRead) => {
|
|
|
|
|
- expect(canRead).to.equal(true)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ testPermission('canUserWriteProjectContent', {
|
|
|
|
|
+ siteAdmin: true,
|
|
|
|
|
+ owner: true,
|
|
|
|
|
+ readAndWrite: true,
|
|
|
|
|
+ publicReadAndWrite: true,
|
|
|
|
|
+ tokenReadAndWrite: true,
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- describe('when user has no access', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, false, false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return false', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserReadProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canRead) => {
|
|
|
|
|
- expect(canRead).to.equal(false)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ testPermission('canUserWriteProjectSettings', {
|
|
|
|
|
+ siteAdmin: true,
|
|
|
|
|
+ owner: true,
|
|
|
|
|
+ readAndWrite: true,
|
|
|
|
|
+ tokenReadAndWrite: true,
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- describe('canUserWriteProjectContent', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return (this.AuthorizationManager.getPrivilegeLevelForProject = sinon.stub())
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ testPermission('canUserRenameProject', {
|
|
|
|
|
+ siteAdmin: true,
|
|
|
|
|
+ owner: true,
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- describe('when user is owner', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'owner', false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return true', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserWriteProjectContent(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canWrite) => {
|
|
|
|
|
- expect(canWrite).to.equal(true)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ testPermission('canUserAdminProject', { siteAdmin: true, owner: true })
|
|
|
|
|
|
|
|
- describe('when user has read-write access', function () {
|
|
|
|
|
|
|
+ describe('isUserSiteAdmin', function () {
|
|
|
|
|
+ describe('when user is admin', function () {
|
|
|
beforeEach(function () {
|
|
beforeEach(function () {
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'readAndWrite', false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return true', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserWriteProjectContent(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canWrite) => {
|
|
|
|
|
- expect(canWrite).to.equal(true)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ this.user.isAdmin = true
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- describe('when user has read-only access', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'readOnly', false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return false', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserWriteProjectContent(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canWrite) => {
|
|
|
|
|
- expect(canWrite).to.equal(false)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ it('should return true', async function () {
|
|
|
|
|
+ const isAdmin = await this.AuthorizationManager.promises.isUserSiteAdmin(
|
|
|
|
|
+ this.user._id
|
|
|
)
|
|
)
|
|
|
|
|
+ expect(isAdmin).to.equal(true)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- describe('when user has no access', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, false, false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return false', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserWriteProjectContent(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canWrite) => {
|
|
|
|
|
- expect(canWrite).to.equal(false)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ describe('when user is not admin', function () {
|
|
|
|
|
+ it('should return false', async function () {
|
|
|
|
|
+ const isAdmin = await this.AuthorizationManager.promises.isUserSiteAdmin(
|
|
|
|
|
+ this.user._id
|
|
|
)
|
|
)
|
|
|
|
|
+ expect(isAdmin).to.equal(false)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- describe('canUserWriteProjectSettings', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return (this.AuthorizationManager.getPrivilegeLevelForProject = sinon.stub())
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- describe('when user is owner', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'owner', false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return true', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserWriteProjectSettings(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canWrite) => {
|
|
|
|
|
- expect(canWrite).to.equal(true)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ describe('when user is not found', function () {
|
|
|
|
|
+ it('should return false', async function () {
|
|
|
|
|
+ const someOtherId = new ObjectId()
|
|
|
|
|
+ const isAdmin = await this.AuthorizationManager.promises.isUserSiteAdmin(
|
|
|
|
|
+ someOtherId
|
|
|
)
|
|
)
|
|
|
|
|
+ expect(isAdmin).to.equal(false)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- describe('when user has read-write access as a collaborator', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'readAndWrite', false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return true', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserWriteProjectSettings(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canWrite) => {
|
|
|
|
|
- expect(canWrite).to.equal(true)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ describe('when no user is passed', function () {
|
|
|
|
|
+ it('should return false', async function () {
|
|
|
|
|
+ const isAdmin = await this.AuthorizationManager.promises.isUserSiteAdmin(
|
|
|
|
|
+ null
|
|
|
)
|
|
)
|
|
|
|
|
+ expect(isAdmin).to.equal(false)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
+ })
|
|
|
|
|
+})
|
|
|
|
|
|
|
|
- describe('when user has read-write access as the public', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'readAndWrite', true)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return false', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserWriteProjectSettings(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canWrite) => {
|
|
|
|
|
- expect(canWrite).to.equal(false)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+function testPermission(permission, privilegeLevels) {
|
|
|
|
|
+ describe(permission, function () {
|
|
|
|
|
+ describe('when authenticated', function () {
|
|
|
|
|
+ describe('when user is site admin', function () {
|
|
|
|
|
+ beforeEach('set user as site admin', function () {
|
|
|
|
|
+ this.user.isAdmin = true
|
|
|
|
|
+ })
|
|
|
|
|
+ expectPermission(permission, privilegeLevels.siteAdmin || false)
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- describe('when user has read-only access', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'readOnly', false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return false', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserWriteProjectSettings(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canWrite) => {
|
|
|
|
|
- expect(canWrite).to.equal(false)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ describe('when user is owner', function () {
|
|
|
|
|
+ setupUserPrivilegeLevel(PrivilegeLevels.OWNER)
|
|
|
|
|
+ expectPermission(permission, privilegeLevels.owner || false)
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- describe('when user has no access', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, false, false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return false', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserWriteProjectSettings(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canWrite) => {
|
|
|
|
|
- expect(canWrite).to.equal(false)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ describe('when user has read-write access', function () {
|
|
|
|
|
+ setupUserPrivilegeLevel(PrivilegeLevels.READ_AND_WRITE)
|
|
|
|
|
+ expectPermission(permission, privilegeLevels.readAndWrite || false)
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- describe('canUserAdminProject', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return (this.AuthorizationManager.getPrivilegeLevelForProject = sinon.stub())
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ describe('when user has read-only access', function () {
|
|
|
|
|
+ setupUserPrivilegeLevel(PrivilegeLevels.READ_ONLY)
|
|
|
|
|
+ expectPermission(permission, privilegeLevels.readOnly || false)
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- describe('when user is owner', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'owner', false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return true', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserAdminProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canAdmin) => {
|
|
|
|
|
- expect(canAdmin).to.equal(true)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ describe('when user has read-write access as the public', function () {
|
|
|
|
|
+ setupPublicAccessLevel(PublicAccessLevels.READ_AND_WRITE)
|
|
|
|
|
+ expectPermission(
|
|
|
|
|
+ permission,
|
|
|
|
|
+ privilegeLevels.publicReadAndWrite || false
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- describe('when user has read-write access', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'readAndWrite', false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return false', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserAdminProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canAdmin) => {
|
|
|
|
|
- expect(canAdmin).to.equal(false)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ describe('when user has read-only access as the public', function () {
|
|
|
|
|
+ setupPublicAccessLevel(PublicAccessLevels.READ_ONLY)
|
|
|
|
|
+ expectPermission(permission, privilegeLevels.publicReadOnly || false)
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- describe('when user has read-only access', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, 'readOnly', false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return false', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserAdminProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canAdmin) => {
|
|
|
|
|
- expect(canAdmin).to.equal(false)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ describe('when user is not found', function () {
|
|
|
|
|
+ it('should return false', async function () {
|
|
|
|
|
+ const otherUserId = new ObjectId()
|
|
|
|
|
+ const value = await this.AuthorizationManager.promises[permission](
|
|
|
|
|
+ otherUserId,
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
|
|
+ )
|
|
|
|
|
+ expect(value).to.equal(false)
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- describe('when user has no access', function () {
|
|
|
|
|
|
|
+ describe('when anonymous', function () {
|
|
|
beforeEach(function () {
|
|
beforeEach(function () {
|
|
|
- return this.AuthorizationManager.getPrivilegeLevelForProject
|
|
|
|
|
- .withArgs(this.user_id, this.project_id, this.token)
|
|
|
|
|
- .yields(null, false, false)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return false', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.canUserAdminProject(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- this.project_id,
|
|
|
|
|
- this.token,
|
|
|
|
|
- (error, canAdmin) => {
|
|
|
|
|
- expect(canAdmin).to.equal(false)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ this.user = null
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- describe('isUserSiteAdmin', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return (this.User.findOne = sinon.stub())
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ describe('with read-write access through a token', function () {
|
|
|
|
|
+ setupTokenAccessLevel('readAndWrite')
|
|
|
|
|
+ expectPermission(permission, privilegeLevels.tokenReadAndWrite || false)
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- describe('when user is admin', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.User.findOne
|
|
|
|
|
- .withArgs({ _id: this.user_id }, { isAdmin: 1 })
|
|
|
|
|
- .yields(null, { isAdmin: true })
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return true', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.isUserSiteAdmin(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- (error, isAdmin) => {
|
|
|
|
|
- expect(isAdmin).to.equal(true)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ describe('with read-only access through a token', function () {
|
|
|
|
|
+ setupTokenAccessLevel('readOnly')
|
|
|
|
|
+ expectPermission(permission, privilegeLevels.tokenReadOnly || false)
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- describe('when user is not admin', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.User.findOne
|
|
|
|
|
- .withArgs({ _id: this.user_id }, { isAdmin: 1 })
|
|
|
|
|
- .yields(null, { isAdmin: false })
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return false', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.isUserSiteAdmin(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- (error, isAdmin) => {
|
|
|
|
|
- expect(isAdmin).to.equal(false)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ describe('with public read-write access', function () {
|
|
|
|
|
+ setupPublicAccessLevel(PublicAccessLevels.READ_AND_WRITE)
|
|
|
|
|
+ expectPermission(
|
|
|
|
|
+ permission,
|
|
|
|
|
+ privilegeLevels.publicReadAndWrite || false
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
|
|
|
|
|
- describe('when user is not found', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- return this.User.findOne
|
|
|
|
|
- .withArgs({ _id: this.user_id }, { isAdmin: 1 })
|
|
|
|
|
- .yields(null, null)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should return false', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.isUserSiteAdmin(
|
|
|
|
|
- this.user_id,
|
|
|
|
|
- (error, isAdmin) => {
|
|
|
|
|
- expect(isAdmin).to.equal(false)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ describe('with public read-only access', function () {
|
|
|
|
|
+ setupPublicAccessLevel(PublicAccessLevels.READ_ONLY)
|
|
|
|
|
+ expectPermission(permission, privilegeLevels.publicReadOnly || false)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- describe('when no user is passed', function () {
|
|
|
|
|
- it('should return false', function (done) {
|
|
|
|
|
- return this.AuthorizationManager.isUserSiteAdmin(
|
|
|
|
|
- null,
|
|
|
|
|
- (error, isAdmin) => {
|
|
|
|
|
- this.User.findOne.called.should.equal(false)
|
|
|
|
|
- expect(isAdmin).to.equal(false)
|
|
|
|
|
- return done()
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
|
|
+function setupUserPrivilegeLevel(privilegeLevel) {
|
|
|
|
|
+ beforeEach(`set user privilege level to ${privilegeLevel}`, function () {
|
|
|
|
|
+ this.CollaboratorsGetter.promises.getMemberIdPrivilegeLevel
|
|
|
|
|
+ .withArgs(this.user._id, this.project._id)
|
|
|
|
|
+ .resolves(privilegeLevel)
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function setupPublicAccessLevel(level) {
|
|
|
|
|
+ beforeEach(`set public access level to ${level}`, function () {
|
|
|
|
|
+ this.project.publicAccesLevel = level
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function setupTokenAccessLevel(level) {
|
|
|
|
|
+ beforeEach(`set token access level to ${level}`, function () {
|
|
|
|
|
+ this.project.publicAccesLevel = PublicAccessLevels.TOKEN_BASED
|
|
|
|
|
+ this.TokenAccessHandler.promises.validateTokenForAnonymousAccess
|
|
|
|
|
+ .withArgs(this.project._id, this.token)
|
|
|
|
|
+ .resolves({
|
|
|
|
|
+ isValidReadAndWrite: level === 'readAndWrite',
|
|
|
|
|
+ isValidReadOnly: level === 'readOnly',
|
|
|
})
|
|
})
|
|
|
- })
|
|
|
|
|
})
|
|
})
|
|
|
-})
|
|
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function expectPermission(permission, expectedValue) {
|
|
|
|
|
+ it(`should return ${expectedValue}`, async function () {
|
|
|
|
|
+ const value = await this.AuthorizationManager.promises[permission](
|
|
|
|
|
+ this.user && this.user._id,
|
|
|
|
|
+ this.project._id,
|
|
|
|
|
+ this.token
|
|
|
|
|
+ )
|
|
|
|
|
+ expect(value).to.equal(expectedValue)
|
|
|
|
|
+ })
|
|
|
|
|
+}
|