2019-05-29 05:21:06 -04:00
|
|
|
const { expect } = require('chai')
|
|
|
|
const async = require('async')
|
|
|
|
const User = require('./helpers/User')
|
|
|
|
const request = require('./helpers/request')
|
2021-07-07 05:38:56 -04:00
|
|
|
const settings = require('@overleaf/settings')
|
2020-10-07 09:16:54 -04:00
|
|
|
const { db, ObjectId } = require('../../../app/src/infrastructure/mongodb')
|
2021-02-25 07:22:24 -05:00
|
|
|
const MockV1ApiClass = require('./mocks/MockV1Api')
|
2020-07-27 06:46:27 -04:00
|
|
|
const expectErrorResponse = require('./helpers/expectErrorResponse')
|
|
|
|
|
2021-02-25 07:22:24 -05:00
|
|
|
let MockV1Api
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
before(function () {
|
2021-02-25 07:22:24 -05:00
|
|
|
MockV1Api = MockV1ApiClass.instance()
|
|
|
|
})
|
|
|
|
|
2020-02-25 04:39:53 -05:00
|
|
|
const tryEditorAccess = (user, projectId, test, callback) =>
|
2019-05-29 05:21:06 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
cb =>
|
2019-08-09 09:09:42 -04:00
|
|
|
user.request.get(`/project/${projectId}`, (error, response, body) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (error != null) {
|
|
|
|
return cb(error)
|
|
|
|
}
|
|
|
|
test(response, body)
|
2019-08-09 09:09:42 -04:00
|
|
|
cb()
|
2019-05-29 05:21:06 -04:00
|
|
|
}),
|
|
|
|
cb =>
|
2019-08-07 10:04:04 -04:00
|
|
|
user.request.get(
|
2019-08-09 09:09:42 -04:00
|
|
|
`/project/${projectId}/download/zip`,
|
2019-08-07 10:04:04 -04:00
|
|
|
(error, response, body) => {
|
|
|
|
if (error != null) {
|
|
|
|
return cb(error)
|
|
|
|
}
|
|
|
|
test(response, body)
|
2019-08-09 09:09:42 -04:00
|
|
|
cb()
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2021-04-27 03:52:58 -04:00
|
|
|
),
|
2019-05-29 05:21:06 -04:00
|
|
|
],
|
|
|
|
callback
|
|
|
|
)
|
|
|
|
|
2020-02-25 04:39:53 -05:00
|
|
|
const tryReadOnlyTokenAccess = (
|
|
|
|
user,
|
|
|
|
token,
|
|
|
|
testPageLoad,
|
|
|
|
testFormPost,
|
|
|
|
callback
|
|
|
|
) => {
|
|
|
|
_doTryTokenAccess(
|
|
|
|
`/read/${token}`,
|
|
|
|
user,
|
|
|
|
token,
|
|
|
|
testPageLoad,
|
|
|
|
testFormPost,
|
|
|
|
callback
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const tryReadAndWriteTokenAccess = (
|
|
|
|
user,
|
|
|
|
token,
|
|
|
|
testPageLoad,
|
|
|
|
testFormPost,
|
|
|
|
callback
|
|
|
|
) => {
|
|
|
|
_doTryTokenAccess(
|
|
|
|
`/${token}`,
|
|
|
|
user,
|
|
|
|
token,
|
|
|
|
testPageLoad,
|
|
|
|
testFormPost,
|
|
|
|
callback
|
|
|
|
)
|
|
|
|
}
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2020-02-25 04:39:53 -05:00
|
|
|
const _doTryTokenAccess = (
|
|
|
|
url,
|
|
|
|
user,
|
|
|
|
token,
|
|
|
|
testPageLoad,
|
|
|
|
testFormPost,
|
|
|
|
callback
|
|
|
|
) => {
|
|
|
|
user.request.get(url, (err, response, body) => {
|
|
|
|
if (err) {
|
|
|
|
return callback(err)
|
2019-08-09 09:09:42 -04:00
|
|
|
}
|
2020-02-25 04:39:53 -05:00
|
|
|
testPageLoad(response, body)
|
|
|
|
if (!testFormPost) {
|
|
|
|
return callback()
|
|
|
|
}
|
|
|
|
user.request.post(
|
|
|
|
`${url}/grant`,
|
|
|
|
{ json: { token } },
|
|
|
|
(err, response, body) => {
|
|
|
|
if (err) {
|
|
|
|
return callback(err)
|
|
|
|
}
|
|
|
|
testFormPost(response, body)
|
|
|
|
callback()
|
|
|
|
}
|
|
|
|
)
|
2019-08-09 09:09:42 -04:00
|
|
|
})
|
2020-02-25 04:39:53 -05:00
|
|
|
}
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2019-08-09 09:09:42 -04:00
|
|
|
const tryContentAccess = (user, projcetId, test, callback) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
// The real-time service calls this end point to determine the user's
|
|
|
|
// permissions.
|
2019-08-09 09:09:42 -04:00
|
|
|
let userId
|
2019-05-29 05:21:06 -04:00
|
|
|
if (user.id != null) {
|
2019-08-09 09:09:42 -04:00
|
|
|
userId = user.id
|
2019-05-29 05:21:06 -04:00
|
|
|
} else {
|
2019-08-09 09:09:42 -04:00
|
|
|
userId = 'anonymous-user'
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
request.post(
|
2019-05-29 05:21:06 -04:00
|
|
|
{
|
2019-08-09 09:09:42 -04:00
|
|
|
url: `/project/${projcetId}/join`,
|
|
|
|
qs: { user_id: userId },
|
2019-05-29 05:21:06 -04:00
|
|
|
auth: {
|
|
|
|
user: settings.apis.web.user,
|
|
|
|
pass: settings.apis.web.pass,
|
2021-04-27 03:52:58 -04:00
|
|
|
sendImmediately: true,
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
json: true,
|
2021-04-27 03:52:58 -04:00
|
|
|
jar: false,
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
2019-08-07 10:04:04 -04:00
|
|
|
(error, response, body) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (error != null) {
|
|
|
|
return callback(error)
|
|
|
|
}
|
|
|
|
test(response, body)
|
2019-08-09 09:09:42 -04:00
|
|
|
callback()
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2019-08-09 09:09:42 -04:00
|
|
|
const tryAnonContentAccess = (user, projectId, token, test, callback) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
// The real-time service calls this end point to determine the user's
|
|
|
|
// permissions.
|
2019-08-09 09:09:42 -04:00
|
|
|
let userId
|
2019-05-29 05:21:06 -04:00
|
|
|
if (user.id != null) {
|
2019-08-09 09:09:42 -04:00
|
|
|
userId = user.id
|
2019-05-29 05:21:06 -04:00
|
|
|
} else {
|
2019-08-09 09:09:42 -04:00
|
|
|
userId = 'anonymous-user'
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
request.post(
|
2019-05-29 05:21:06 -04:00
|
|
|
{
|
2019-08-09 09:09:42 -04:00
|
|
|
url: `/project/${projectId}/join`,
|
|
|
|
qs: { user_id: userId },
|
2019-05-29 05:21:06 -04:00
|
|
|
auth: {
|
|
|
|
user: settings.apis.web.user,
|
|
|
|
pass: settings.apis.web.pass,
|
2021-04-27 03:52:58 -04:00
|
|
|
sendImmediately: true,
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
headers: {
|
2021-04-27 03:52:58 -04:00
|
|
|
'x-sl-anonymous-access-token': token,
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
json: true,
|
2021-04-27 03:52:58 -04:00
|
|
|
jar: false,
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
2019-08-07 10:04:04 -04:00
|
|
|
(error, response, body) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (error != null) {
|
|
|
|
return callback(error)
|
|
|
|
}
|
|
|
|
test(response, body)
|
2019-08-09 09:09:42 -04:00
|
|
|
callback()
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('TokenAccess', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.timeout(90000)
|
|
|
|
this.owner = new User()
|
|
|
|
this.other1 = new User()
|
|
|
|
this.other2 = new User()
|
|
|
|
this.anon = new User()
|
2020-02-25 04:39:53 -05:00
|
|
|
this.siteAdmin = new User({ email: 'admin@example.com' })
|
2019-08-09 09:09:42 -04:00
|
|
|
async.parallel(
|
2019-05-29 05:21:06 -04:00
|
|
|
[
|
2020-02-25 04:39:53 -05:00
|
|
|
cb =>
|
|
|
|
this.siteAdmin.login(err => {
|
|
|
|
if (err) {
|
|
|
|
return cb(err)
|
|
|
|
}
|
|
|
|
this.siteAdmin.ensureAdmin(cb)
|
|
|
|
}),
|
2019-05-29 05:21:06 -04:00
|
|
|
cb => this.owner.login(cb),
|
|
|
|
cb => this.other1.login(cb),
|
|
|
|
cb => this.other2.login(cb),
|
2021-04-27 03:52:58 -04:00
|
|
|
cb => this.anon.getCsrfToken(cb),
|
2019-05-29 05:21:06 -04:00
|
|
|
],
|
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('no token-access', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.createProject(
|
2019-05-29 05:21:06 -04:00
|
|
|
`token-ro-test${Math.random()}`,
|
2019-08-09 09:09:42 -04:00
|
|
|
(err, projectId) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
this.projectId = projectId
|
2019-05-29 05:21:06 -04:00
|
|
|
// Note, never made token-based,
|
|
|
|
// thus no tokens
|
2019-08-09 09:09:42 -04:00
|
|
|
done()
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should deny access ', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
cb => {
|
2020-02-25 04:39:53 -05:00
|
|
|
tryEditorAccess(
|
2019-08-09 09:09:42 -04:00
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
)
|
|
|
|
},
|
|
|
|
cb => {
|
|
|
|
tryContentAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
2019-11-07 05:28:34 -05:00
|
|
|
expect(response.statusCode).to.equal(403)
|
|
|
|
expect(body).to.equal('Forbidden')
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
|
|
|
)
|
2021-04-27 03:52:58 -04:00
|
|
|
},
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('read-only token', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.createProject(
|
2019-05-29 05:21:06 -04:00
|
|
|
`token-ro-test${Math.random()}`,
|
2019-08-09 09:09:42 -04:00
|
|
|
(err, projectId) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
this.projectId = projectId
|
|
|
|
this.owner.makeTokenBased(this.projectId, err => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.getProject(this.projectId, (err, project) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.tokens = project.tokens
|
2019-08-09 09:09:42 -04:00
|
|
|
done()
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('allow the user read-only access to the project', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
cb => {
|
|
|
|
// deny access before token is used
|
2020-02-25 04:39:53 -05:00
|
|
|
tryEditorAccess(
|
2019-08-09 09:09:42 -04:00
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
)
|
|
|
|
},
|
|
|
|
cb => {
|
|
|
|
// use token
|
|
|
|
tryReadOnlyTokenAccess(
|
|
|
|
this.other1,
|
|
|
|
this.tokens.readOnly,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
2020-02-25 04:39:53 -05:00
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(body.redirect).to.equal(`/project/${this.projectId}`)
|
|
|
|
expect(body.tokenAccessGranted).to.equal('readOnly')
|
|
|
|
},
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
)
|
|
|
|
},
|
|
|
|
cb => {
|
|
|
|
// allow content access read-only
|
|
|
|
tryContentAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(body.privilegeLevel).to.equal('readOnly')
|
2019-10-18 05:32:19 -04:00
|
|
|
expect(body.isRestrictedUser).to.equal(true)
|
|
|
|
expect(body.project.owner).to.have.keys('_id')
|
|
|
|
expect(body.project.owner).to.not.have.any.keys(
|
|
|
|
'email',
|
|
|
|
'first_name',
|
|
|
|
'last_name'
|
|
|
|
)
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
|
|
|
)
|
2020-02-25 04:39:53 -05:00
|
|
|
},
|
|
|
|
cb => {
|
|
|
|
tryEditorAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
)
|
2021-04-27 03:52:58 -04:00
|
|
|
},
|
2020-02-25 04:39:53 -05:00
|
|
|
],
|
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should redirect the admin to the project (with rw access)', function (done) {
|
2020-02-25 04:39:53 -05:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
cb => {
|
|
|
|
// use token
|
|
|
|
tryReadOnlyTokenAccess(
|
|
|
|
this.siteAdmin,
|
|
|
|
this.tokens.readOnly,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(body.redirect).to.equal(`/project/${this.projectId}`)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
)
|
|
|
|
},
|
|
|
|
cb => {
|
|
|
|
// allow content access read-and-write
|
|
|
|
tryContentAccess(
|
|
|
|
this.siteAdmin,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(body.privilegeLevel).to.equal('owner')
|
|
|
|
expect(body.isRestrictedUser).to.equal(false)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
)
|
2021-04-27 03:52:58 -04:00
|
|
|
},
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('made private again', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.makePrivate(this.projectId, () => setTimeout(done, 1000))
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should not allow the user to access the project', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
// no access before token is used
|
|
|
|
cb =>
|
2020-02-25 04:39:53 -05:00
|
|
|
tryEditorAccess(
|
2019-08-09 09:09:42 -04:00
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
),
|
2020-02-25 04:39:53 -05:00
|
|
|
// token goes nowhere
|
2019-08-09 09:09:42 -04:00
|
|
|
cb =>
|
|
|
|
tryReadOnlyTokenAccess(
|
|
|
|
this.other1,
|
|
|
|
this.tokens.readOnly,
|
2020-02-25 04:39:53 -05:00
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
2019-08-09 09:09:42 -04:00
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(404)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
2020-02-25 04:39:53 -05:00
|
|
|
// still no access
|
|
|
|
cb =>
|
|
|
|
tryEditorAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2020-02-25 04:39:53 -05:00
|
|
|
cb
|
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
cb =>
|
|
|
|
tryContentAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
2019-11-07 05:28:34 -05:00
|
|
|
expect(response.statusCode).to.equal(403)
|
|
|
|
expect(body).to.equal('Forbidden')
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
2021-04-27 03:52:58 -04:00
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('anonymous read-only token', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.createProject(
|
2019-05-29 05:21:06 -04:00
|
|
|
`token-anon-ro-test${Math.random()}`,
|
2019-08-09 09:09:42 -04:00
|
|
|
(err, projectId) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
this.projectId = projectId
|
|
|
|
this.owner.makeTokenBased(this.projectId, err => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.getProject(this.projectId, (err, project) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.tokens = project.tokens
|
2019-08-09 09:09:42 -04:00
|
|
|
done()
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should allow the user to access project via read-only token url', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
cb =>
|
2020-02-25 04:39:53 -05:00
|
|
|
tryEditorAccess(
|
2019-08-09 09:09:42 -04:00
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryReadOnlyTokenAccess(
|
|
|
|
this.anon,
|
|
|
|
this.tokens.readOnly,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
2020-02-25 04:39:53 -05:00
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(body.redirect).to.equal(`/project/${this.projectId}`)
|
|
|
|
expect(body.grantAnonymousAccess).to.equal('readOnly')
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryEditorAccess(
|
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryAnonContentAccess(
|
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
|
|
|
this.tokens.readOnly,
|
|
|
|
(response, body) => {
|
|
|
|
expect(body.privilegeLevel).to.equal('readOnly')
|
2019-10-18 05:32:19 -04:00
|
|
|
expect(body.isRestrictedUser).to.equal(true)
|
|
|
|
expect(body.project.owner).to.have.keys('_id')
|
|
|
|
expect(body.project.owner).to.not.have.any.keys(
|
|
|
|
'email',
|
|
|
|
'first_name',
|
|
|
|
'last_name'
|
|
|
|
)
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
2021-04-27 03:52:58 -04:00
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('made private again', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.makePrivate(this.projectId, () => setTimeout(done, 1000))
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should deny access to project', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
cb =>
|
2020-02-25 04:39:53 -05:00
|
|
|
tryEditorAccess(
|
2019-08-09 09:09:42 -04:00
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
),
|
|
|
|
// should not allow the user to access read-only token
|
|
|
|
cb =>
|
|
|
|
tryReadOnlyTokenAccess(
|
|
|
|
this.anon,
|
|
|
|
this.tokens.readOnly,
|
2020-02-25 04:39:53 -05:00
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
2019-08-09 09:09:42 -04:00
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(404)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
2020-02-25 04:39:53 -05:00
|
|
|
// still no access
|
|
|
|
cb =>
|
|
|
|
tryEditorAccess(
|
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2020-02-25 04:39:53 -05:00
|
|
|
cb
|
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
// should not allow the user to join the project
|
|
|
|
cb =>
|
|
|
|
tryAnonContentAccess(
|
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
|
|
|
this.tokens.readOnly,
|
|
|
|
(response, body) => {
|
2019-11-07 05:28:34 -05:00
|
|
|
expect(response.statusCode).to.equal(403)
|
|
|
|
expect(body).to.equal('Forbidden')
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
2021-04-27 03:52:58 -04:00
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('read-and-write token', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.createProject(
|
2019-05-29 05:21:06 -04:00
|
|
|
`token-rw-test${Math.random()}`,
|
2019-08-09 09:09:42 -04:00
|
|
|
(err, projectId) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
this.projectId = projectId
|
|
|
|
this.owner.makeTokenBased(this.projectId, err => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.getProject(this.projectId, (err, project) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.tokens = project.tokens
|
2019-08-09 09:09:42 -04:00
|
|
|
done()
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should allow the user to access project via read-and-write token url', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
// deny access before the token is used
|
|
|
|
cb =>
|
2020-02-25 04:39:53 -05:00
|
|
|
tryEditorAccess(
|
2019-08-09 09:09:42 -04:00
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryReadAndWriteTokenAccess(
|
|
|
|
this.other1,
|
|
|
|
this.tokens.readAndWrite,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
2020-02-25 04:39:53 -05:00
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(body.redirect).to.equal(`/project/${this.projectId}`)
|
|
|
|
expect(body.tokenAccessGranted).to.equal('readAndWrite')
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryEditorAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryContentAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(body.privilegeLevel).to.equal('readAndWrite')
|
2019-10-18 05:32:19 -04:00
|
|
|
expect(body.isRestrictedUser).to.equal(false)
|
|
|
|
expect(body.project.owner).to.have.all.keys(
|
|
|
|
'_id',
|
|
|
|
'email',
|
|
|
|
'first_name',
|
|
|
|
'last_name',
|
|
|
|
'privileges',
|
|
|
|
'signUpDate'
|
|
|
|
)
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
2021-04-27 03:52:58 -04:00
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('upgrading from a read-only token', function () {
|
|
|
|
beforeEach(function (done) {
|
2020-02-25 04:39:53 -05:00
|
|
|
this.owner.createProject(
|
|
|
|
`token-rw-upgrade-test${Math.random()}`,
|
|
|
|
(err, projectId) => {
|
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.projectId = projectId
|
|
|
|
this.owner.makeTokenBased(this.projectId, err => {
|
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.owner.getProject(this.projectId, (err, project) => {
|
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.tokens = project.tokens
|
|
|
|
done()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should allow user to access project via read-only, then upgrade to read-write', function (done) {
|
2020-02-25 04:39:53 -05:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
// deny access before the token is used
|
|
|
|
cb =>
|
|
|
|
tryEditorAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2020-02-25 04:39:53 -05:00
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb => {
|
|
|
|
// use read-only token
|
|
|
|
tryReadOnlyTokenAccess(
|
|
|
|
this.other1,
|
|
|
|
this.tokens.readOnly,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(body.redirect).to.equal(`/project/${this.projectId}`)
|
|
|
|
expect(body.tokenAccessGranted).to.equal('readOnly')
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
)
|
|
|
|
},
|
|
|
|
cb => {
|
|
|
|
tryEditorAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
)
|
|
|
|
},
|
|
|
|
cb => {
|
|
|
|
// allow content access read-only
|
|
|
|
tryContentAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(body.privilegeLevel).to.equal('readOnly')
|
|
|
|
expect(body.isRestrictedUser).to.equal(true)
|
|
|
|
expect(body.project.owner).to.have.keys('_id')
|
|
|
|
expect(body.project.owner).to.not.have.any.keys(
|
|
|
|
'email',
|
|
|
|
'first_name',
|
|
|
|
'last_name'
|
|
|
|
)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
)
|
|
|
|
},
|
|
|
|
//
|
|
|
|
// Then switch to read-write token
|
|
|
|
//
|
|
|
|
cb =>
|
|
|
|
tryReadAndWriteTokenAccess(
|
|
|
|
this.other1,
|
|
|
|
this.tokens.readAndWrite,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(body.redirect).to.equal(`/project/${this.projectId}`)
|
|
|
|
expect(body.tokenAccessGranted).to.equal('readAndWrite')
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryEditorAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryContentAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(body.privilegeLevel).to.equal('readAndWrite')
|
|
|
|
expect(body.isRestrictedUser).to.equal(false)
|
|
|
|
expect(body.project.owner).to.have.all.keys(
|
|
|
|
'_id',
|
|
|
|
'email',
|
|
|
|
'first_name',
|
|
|
|
'last_name',
|
|
|
|
'privileges',
|
|
|
|
'signUpDate'
|
|
|
|
)
|
|
|
|
},
|
|
|
|
cb
|
2021-04-27 03:52:58 -04:00
|
|
|
),
|
2020-02-25 04:39:53 -05:00
|
|
|
],
|
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('made private again', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.makePrivate(this.projectId, () => setTimeout(done, 1000))
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should deny access to project', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
cb => {
|
2020-02-25 04:39:53 -05:00
|
|
|
tryEditorAccess(
|
2019-08-09 09:09:42 -04:00
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
(response, body) => {},
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
)
|
|
|
|
},
|
|
|
|
cb => {
|
|
|
|
tryReadAndWriteTokenAccess(
|
|
|
|
this.other1,
|
|
|
|
this.tokens.readAndWrite,
|
2020-02-25 04:39:53 -05:00
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
2019-08-09 09:09:42 -04:00
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(404)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
)
|
|
|
|
},
|
2020-02-25 04:39:53 -05:00
|
|
|
cb => {
|
|
|
|
tryEditorAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2020-02-25 04:39:53 -05:00
|
|
|
cb
|
|
|
|
)
|
|
|
|
},
|
2019-08-09 09:09:42 -04:00
|
|
|
cb => {
|
|
|
|
tryContentAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
2019-11-07 05:28:34 -05:00
|
|
|
expect(response.statusCode).to.equal(403)
|
|
|
|
expect(body).to.equal('Forbidden')
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
|
|
|
)
|
2021-04-27 03:52:58 -04:00
|
|
|
},
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
if (!settings.allowAnonymousReadAndWriteSharing) {
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('anonymous read-and-write token, disabled', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.createProject(
|
2019-05-29 05:21:06 -04:00
|
|
|
`token-anon-rw-test${Math.random()}`,
|
2019-08-09 09:09:42 -04:00
|
|
|
(err, projectId) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
this.projectId = projectId
|
|
|
|
this.owner.makeTokenBased(this.projectId, err => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.getProject(this.projectId, (err, project) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.tokens = project.tokens
|
2019-08-09 09:09:42 -04:00
|
|
|
done()
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should not allow the user to access read-and-write token', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
cb =>
|
2020-02-25 04:39:53 -05:00
|
|
|
tryEditorAccess(
|
2019-08-09 09:09:42 -04:00
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryReadAndWriteTokenAccess(
|
|
|
|
this.anon,
|
|
|
|
this.tokens.readAndWrite,
|
|
|
|
(response, body) => {
|
2020-02-25 04:39:53 -05:00
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(body).to.deep.equal({
|
|
|
|
redirect: '/restricted',
|
2021-04-27 03:52:58 -04:00
|
|
|
anonWriteAccessDenied: true,
|
2020-02-25 04:39:53 -05:00
|
|
|
})
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryAnonContentAccess(
|
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
|
|
|
this.tokens.readAndWrite,
|
|
|
|
(response, body) => {
|
2019-11-07 05:28:34 -05:00
|
|
|
expect(response.statusCode).to.equal(403)
|
|
|
|
expect(body).to.equal('Forbidden')
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
2020-02-25 08:52:02 -05:00
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
this.anon.login((err, response, body) => {
|
|
|
|
expect(err).to.not.exist
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(body.redir).to.equal(`/${this.tokens.readAndWrite}`)
|
|
|
|
cb()
|
2021-04-27 03:52:58 -04:00
|
|
|
}),
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
} else {
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('anonymous read-and-write token, enabled', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.createProject(
|
2019-05-29 05:21:06 -04:00
|
|
|
`token-anon-rw-test${Math.random()}`,
|
2019-08-09 09:09:42 -04:00
|
|
|
(err, projectId) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
this.projectId = projectId
|
|
|
|
this.owner.makeTokenBased(this.projectId, err => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.getProject(this.projectId, (err, project) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.tokens = project.tokens
|
2019-08-09 09:09:42 -04:00
|
|
|
done()
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should allow the user to access project via read-and-write token url', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
cb =>
|
2020-02-25 04:39:53 -05:00
|
|
|
tryEditorAccess(
|
2019-08-09 09:09:42 -04:00
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryReadAndWriteTokenAccess(
|
|
|
|
this.anon,
|
|
|
|
this.tokens.readAndWrite,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
2020-02-25 04:39:53 -05:00
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(body.redirect).to.equal(`/project/${this.projectId}`)
|
|
|
|
expect(body.grantAnonymousAccess).to.equal('readAndWrite')
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryEditorAccess(
|
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryAnonContentAccess(
|
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
|
|
|
this.tokens.readAndWrite,
|
|
|
|
(response, body) => {
|
|
|
|
expect(body.privilegeLevel).to.equal('readAndWrite')
|
|
|
|
},
|
|
|
|
cb
|
2021-04-27 03:52:58 -04:00
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('made private again', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.makePrivate(this.projectId, () => setTimeout(done, 1000))
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should not allow the user to access read-and-write token', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
cb =>
|
2020-02-25 04:39:53 -05:00
|
|
|
tryEditorAccess(
|
2019-08-09 09:09:42 -04:00
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2019-08-09 09:09:42 -04:00
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryReadAndWriteTokenAccess(
|
|
|
|
this.anon,
|
|
|
|
this.tokens.readAndWrite,
|
2020-02-25 04:39:53 -05:00
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
2019-08-09 09:09:42 -04:00
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(404)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
2020-02-25 04:39:53 -05:00
|
|
|
cb =>
|
|
|
|
tryEditorAccess(
|
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2020-02-25 04:39:53 -05:00
|
|
|
cb
|
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
cb =>
|
|
|
|
tryAnonContentAccess(
|
|
|
|
this.anon,
|
|
|
|
this.projectId,
|
|
|
|
this.tokens.readAndWrite,
|
|
|
|
(response, body) => {
|
2019-11-07 05:28:34 -05:00
|
|
|
expect(response.statusCode).to.equal(403)
|
|
|
|
expect(body).to.equal('Forbidden')
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
2021-04-27 03:52:58 -04:00
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('private overleaf project', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.createProject('overleaf-import', (err, projectId) => {
|
|
|
|
expect(err).not.to.exist
|
|
|
|
this.projectId = projectId
|
|
|
|
this.owner.makeTokenBased(this.projectId, err => {
|
|
|
|
expect(err).not.to.exist
|
|
|
|
this.owner.getProject(this.projectId, (err, project) => {
|
|
|
|
expect(err).not.to.exist
|
2019-05-29 05:21:06 -04:00
|
|
|
this.tokens = project.tokens
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.makePrivate(this.projectId, () => {
|
2020-10-07 09:16:54 -04:00
|
|
|
db.projects.updateOne(
|
2019-05-29 05:21:06 -04:00
|
|
|
{ _id: project._id },
|
|
|
|
{
|
|
|
|
$set: {
|
2021-04-27 03:52:58 -04:00
|
|
|
overleaf: { id: 1234 },
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
err => {
|
2019-08-09 09:09:42 -04:00
|
|
|
expect(err).not.to.exist
|
|
|
|
done()
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should only allow the owner access to the project', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
// should redirect to canonical path, when owner uses read-write token
|
|
|
|
cb =>
|
|
|
|
tryReadAndWriteTokenAccess(
|
|
|
|
this.owner,
|
|
|
|
this.tokens.readAndWrite,
|
|
|
|
(response, body) => {
|
2020-02-25 04:39:53 -05:00
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(response.body.redirect).to.equal(
|
2019-08-09 09:09:42 -04:00
|
|
|
`/project/${this.projectId}`
|
|
|
|
)
|
2020-02-25 04:39:53 -05:00
|
|
|
expect(response.body.higherAccess).to.equal(true)
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
2020-02-25 04:39:53 -05:00
|
|
|
tryEditorAccess(
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryContentAccess(
|
|
|
|
this.owner,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(body.privilegeLevel).to.equal('owner')
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
// non-owner should be denied access
|
|
|
|
cb =>
|
|
|
|
tryContentAccess(
|
|
|
|
this.other2,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
2019-11-07 05:28:34 -05:00
|
|
|
expect(response.statusCode).to.equal(403)
|
|
|
|
expect(body).to.equal('Forbidden')
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
2021-04-27 03:52:58 -04:00
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('private project, with higher access', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.createProject(
|
2019-05-29 05:21:06 -04:00
|
|
|
`higher-access-test-${Math.random()}`,
|
2019-08-09 09:09:42 -04:00
|
|
|
(err, projectId) => {
|
|
|
|
expect(err).not.to.exist
|
|
|
|
this.projectId = projectId
|
|
|
|
this.owner.addUserToProject(
|
|
|
|
this.projectId,
|
2019-05-29 05:21:06 -04:00
|
|
|
this.other1,
|
|
|
|
'readAndWrite',
|
|
|
|
err => {
|
2019-08-09 09:09:42 -04:00
|
|
|
expect(err).not.to.exist
|
|
|
|
this.owner.makeTokenBased(this.projectId, err => {
|
|
|
|
expect(err).not.to.exist
|
|
|
|
this.owner.getProject(this.projectId, (err, project) => {
|
|
|
|
expect(err).not.to.exist
|
|
|
|
this.tokens = project.tokens
|
|
|
|
this.owner.makePrivate(this.projectId, () => {
|
|
|
|
setTimeout(done, 1000)
|
|
|
|
})
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should allow the user access to the project', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
// should redirect to canonical path, when user uses read-write token
|
|
|
|
cb =>
|
|
|
|
tryReadAndWriteTokenAccess(
|
|
|
|
this.other1,
|
|
|
|
this.tokens.readAndWrite,
|
|
|
|
(response, body) => {
|
2020-02-25 04:39:53 -05:00
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(response.body.redirect).to.equal(
|
2019-08-09 09:09:42 -04:00
|
|
|
`/project/${this.projectId}`
|
|
|
|
)
|
2020-02-25 04:39:53 -05:00
|
|
|
expect(response.body.higherAccess).to.equal(true)
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
// should redirect to canonical path, when user uses read-only token
|
|
|
|
cb =>
|
|
|
|
tryReadOnlyTokenAccess(
|
|
|
|
this.other1,
|
|
|
|
this.tokens.readOnly,
|
|
|
|
(response, body) => {
|
2020-02-25 04:39:53 -05:00
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(response.body.redirect).to.equal(
|
2019-08-09 09:09:42 -04:00
|
|
|
`/project/${this.projectId}`
|
|
|
|
)
|
2020-02-25 04:39:53 -05:00
|
|
|
expect(response.body.higherAccess).to.equal(true)
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
// should allow the user access to the project
|
|
|
|
cb =>
|
2020-02-25 04:39:53 -05:00
|
|
|
tryEditorAccess(
|
2019-08-09 09:09:42 -04:00
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
// should allow user to join the project
|
|
|
|
cb =>
|
|
|
|
tryContentAccess(
|
|
|
|
this.other1,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(body.privilegeLevel).to.equal('readAndWrite')
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
// should not allow a different user to join the project
|
2020-02-25 04:39:53 -05:00
|
|
|
cb =>
|
|
|
|
tryEditorAccess(
|
|
|
|
this.other2,
|
|
|
|
this.projectId,
|
2020-07-27 06:46:27 -04:00
|
|
|
expectErrorResponse.restricted.html,
|
2020-02-25 04:39:53 -05:00
|
|
|
cb
|
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
cb =>
|
|
|
|
tryContentAccess(
|
|
|
|
this.other2,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
2019-11-07 05:28:34 -05:00
|
|
|
expect(response.statusCode).to.equal(403)
|
|
|
|
expect(body).to.equal('Forbidden')
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
2021-04-27 03:52:58 -04:00
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-06-24 04:27:19 -04:00
|
|
|
describe('deleted project', function () {
|
|
|
|
beforeEach(function (done) {
|
|
|
|
settings.overleaf = { host: 'http://localhost:5000' }
|
|
|
|
this.owner.createProject(
|
|
|
|
`delete-test${Math.random()}`,
|
|
|
|
(err, projectId) => {
|
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.projectId = projectId
|
|
|
|
this.owner.makeTokenBased(this.projectId, err => {
|
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.owner.getProject(this.projectId, (err, project) => {
|
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.tokens = project.tokens
|
|
|
|
done()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
afterEach(function () {
|
|
|
|
delete settings.overleaf
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should 404', function (done) {
|
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
// delete project
|
|
|
|
cb => {
|
|
|
|
this.owner.deleteProject(this.projectId, cb)
|
|
|
|
},
|
|
|
|
cb => {
|
|
|
|
// use read-only token
|
|
|
|
tryReadOnlyTokenAccess(
|
|
|
|
this.other1,
|
|
|
|
this.tokens.readOnly,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(404)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
)
|
|
|
|
},
|
|
|
|
cb => {
|
|
|
|
// use read-write token
|
|
|
|
tryReadAndWriteTokenAccess(
|
|
|
|
this.other1,
|
|
|
|
this.tokens.readAndWrite,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(404)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
)
|
|
|
|
},
|
|
|
|
],
|
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('unimported v1 project', function () {
|
|
|
|
beforeEach(function () {
|
2019-08-09 09:09:42 -04:00
|
|
|
settings.overleaf = { host: 'http://localhost:5000' }
|
2019-08-07 10:04:04 -04:00
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
afterEach(function () {
|
2019-08-09 09:09:42 -04:00
|
|
|
delete settings.overleaf
|
2019-08-07 10:04:04 -04:00
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2021-06-24 04:27:19 -04:00
|
|
|
it('should show download option for read and write token', function (done) {
|
2020-02-25 04:39:53 -05:00
|
|
|
const unimportedV1Token = '123abcdefabcdef'
|
2021-06-24 04:27:19 -04:00
|
|
|
const docInfo = {
|
|
|
|
exists: true,
|
|
|
|
exported: false,
|
|
|
|
has_owner: true,
|
|
|
|
name: 'test',
|
|
|
|
}
|
|
|
|
MockV1Api.setDocInfo(unimportedV1Token, docInfo)
|
2019-08-09 09:09:42 -04:00
|
|
|
tryReadAndWriteTokenAccess(
|
2019-05-29 05:21:06 -04:00
|
|
|
this.owner,
|
|
|
|
unimportedV1Token,
|
|
|
|
(response, body) => {
|
2020-02-25 04:39:53 -05:00
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
2021-06-24 04:27:19 -04:00
|
|
|
expect(body).to.deep.equal({
|
|
|
|
v1Import: {
|
|
|
|
hasOwner: true,
|
|
|
|
name: 'test',
|
|
|
|
projectId: unimportedV1Token,
|
|
|
|
status: 'canDownloadZip',
|
|
|
|
},
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-06-24 04:27:19 -04:00
|
|
|
it('should show download option for read only token to v1', function (done) {
|
2020-02-25 04:39:53 -05:00
|
|
|
const unimportedV1Token = 'aaaaaabbbbbb'
|
2021-06-24 04:27:19 -04:00
|
|
|
const docInfo = {
|
|
|
|
exists: true,
|
|
|
|
exported: false,
|
|
|
|
has_owner: true,
|
|
|
|
name: 'test',
|
|
|
|
}
|
|
|
|
MockV1Api.setDocInfo(unimportedV1Token, docInfo)
|
2019-08-09 09:09:42 -04:00
|
|
|
tryReadOnlyTokenAccess(
|
2019-05-29 05:21:06 -04:00
|
|
|
this.owner,
|
|
|
|
unimportedV1Token,
|
|
|
|
(response, body) => {
|
2020-02-25 04:39:53 -05:00
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
2021-06-24 04:27:19 -04:00
|
|
|
expect(body).to.deep.equal({
|
|
|
|
v1Import: {
|
|
|
|
hasOwner: true,
|
|
|
|
name: 'test',
|
|
|
|
projectId: unimportedV1Token,
|
|
|
|
status: 'canDownloadZip',
|
|
|
|
},
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('importing v1 project', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
settings.projectImportingCheckMaxCreateDelta = 3600
|
|
|
|
settings.overleaf = { host: 'http://localhost:5000' }
|
2019-08-09 09:09:42 -04:00
|
|
|
this.owner.createProject(
|
2019-05-29 05:21:06 -04:00
|
|
|
`token-rw-test${Math.random()}`,
|
2019-08-09 09:09:42 -04:00
|
|
|
(err, projectId) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2019-08-09 09:09:42 -04:00
|
|
|
this.projectId = projectId
|
2020-10-07 09:16:54 -04:00
|
|
|
db.users.updateOne(
|
2020-02-25 04:39:53 -05:00
|
|
|
{ _id: ObjectId(this.owner._id.toString()) },
|
|
|
|
{ $set: { 'overleaf.id': 321321 } },
|
|
|
|
err => {
|
|
|
|
if (err) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.owner.makeTokenBased(this.projectId, err => {
|
2019-05-29 05:21:06 -04:00
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
2020-10-07 09:16:54 -04:00
|
|
|
db.projects.updateOne(
|
2020-02-25 04:39:53 -05:00
|
|
|
{ _id: ObjectId(projectId) },
|
|
|
|
{ $set: { overleaf: { id: 1234 } } },
|
|
|
|
err => {
|
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.owner.getProject(this.projectId, (err, project) => {
|
|
|
|
if (err != null) {
|
|
|
|
return done(err)
|
|
|
|
}
|
|
|
|
this.tokens = project.tokens
|
|
|
|
const docInfo = {
|
|
|
|
exists: true,
|
|
|
|
exported: false,
|
|
|
|
has_owner: true,
|
2021-04-27 03:52:58 -04:00
|
|
|
name: 'Test Project Import Example',
|
2020-02-25 04:39:53 -05:00
|
|
|
}
|
|
|
|
MockV1Api.setDocInfo(this.tokens.readAndWrite, docInfo)
|
|
|
|
MockV1Api.setDocInfo(this.tokens.readOnly, docInfo)
|
2020-10-07 09:16:54 -04:00
|
|
|
db.projects.deleteOne({ _id: ObjectId(projectId) }, done)
|
2020-02-25 04:39:53 -05:00
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2020-02-25 04:39:53 -05:00
|
|
|
)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
afterEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
delete settings.projectImportingCheckMaxCreateDelta
|
2019-08-09 09:09:42 -04:00
|
|
|
delete settings.overleaf
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should show importing page for read, and read-write tokens', function (done) {
|
2019-08-09 09:09:42 -04:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
cb =>
|
|
|
|
tryReadAndWriteTokenAccess(
|
|
|
|
this.owner,
|
|
|
|
this.tokens.readAndWrite,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
2020-02-25 04:39:53 -05:00
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(body).to.deep.equal({
|
|
|
|
v1Import: {
|
2020-05-20 09:02:50 -04:00
|
|
|
status: 'canDownloadZip',
|
2020-02-25 04:39:53 -05:00
|
|
|
projectId: this.tokens.readAndWrite,
|
|
|
|
hasOwner: true,
|
2021-04-27 03:52:58 -04:00
|
|
|
name: 'Test Project Import Example',
|
|
|
|
},
|
2020-02-25 04:39:53 -05:00
|
|
|
})
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryReadOnlyTokenAccess(
|
|
|
|
this.owner,
|
|
|
|
this.tokens.readOnly,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
2020-02-25 04:39:53 -05:00
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
expect(body).to.deep.equal({
|
|
|
|
v1Import: {
|
2020-05-20 09:02:50 -04:00
|
|
|
status: 'canDownloadZip',
|
2020-02-25 04:39:53 -05:00
|
|
|
projectId: this.tokens.readOnly,
|
|
|
|
hasOwner: true,
|
2021-04-27 03:52:58 -04:00
|
|
|
name: 'Test Project Import Example',
|
|
|
|
},
|
2020-02-25 04:39:53 -05:00
|
|
|
})
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryEditorAccess(
|
|
|
|
this.owner,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(404)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryContentAccess(
|
|
|
|
this.other2,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(404)
|
2019-08-09 09:09:42 -04:00
|
|
|
},
|
|
|
|
cb
|
2021-04-27 03:52:58 -04:00
|
|
|
),
|
2019-08-09 09:09:42 -04:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('when the v1 doc does not exist', function (done) {
|
|
|
|
beforeEach(function (done) {
|
2020-02-25 04:39:53 -05:00
|
|
|
const docInfo = null
|
|
|
|
MockV1Api.setDocInfo(this.tokens.readAndWrite, docInfo)
|
|
|
|
MockV1Api.setDocInfo(this.tokens.readOnly, docInfo)
|
|
|
|
done()
|
2019-08-07 10:04:04 -04:00
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should get a 404 response on the post endpoint', function (done) {
|
2020-02-25 04:39:53 -05:00
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
cb =>
|
|
|
|
tryReadAndWriteTokenAccess(
|
|
|
|
this.owner,
|
|
|
|
this.tokens.readAndWrite,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(404)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryReadOnlyTokenAccess(
|
|
|
|
this.owner,
|
|
|
|
this.tokens.readOnly,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(200)
|
|
|
|
},
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(404)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryEditorAccess(
|
|
|
|
this.owner,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(404)
|
|
|
|
},
|
|
|
|
cb
|
|
|
|
),
|
|
|
|
cb =>
|
|
|
|
tryContentAccess(
|
|
|
|
this.other2,
|
|
|
|
this.projectId,
|
|
|
|
(response, body) => {
|
|
|
|
expect(response.statusCode).to.equal(404)
|
|
|
|
},
|
|
|
|
cb
|
2021-04-27 03:52:58 -04:00
|
|
|
),
|
2020-02-25 04:39:53 -05:00
|
|
|
],
|
2019-05-29 05:21:06 -04:00
|
|
|
done
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|