Merge pull request #8897 from overleaf/ta-token-access-anonymous-redirect

Redirect Early on Anonymous Write Token Access Attempts

GitOrigin-RevId: 55e1839c3171a0a6a677ecca2f6bec87aad802bd
This commit is contained in:
Timothée Alby 2022-07-28 11:21:02 +02:00 committed by Copybot
parent 7f722a006c
commit ff3e659fbb
2 changed files with 89 additions and 17 deletions

View file

@ -113,6 +113,28 @@ async function checkAndGetProjectOrResponseAction(
res, res,
next next
) { ) {
const isAnonymousUser = !userId
if (
isAnonymousUser &&
tokenType === TokenAccessHandler.TOKEN_TYPES.READ_AND_WRITE &&
!TokenAccessHandler.ANONYMOUS_READ_AND_WRITE_ENABLED
) {
logger.warn('[TokenAccess] deny anonymous read-and-write token access')
AuthenticationController.setRedirectInSession(
req,
TokenAccessHandler.makeTokenUrl(token)
)
return [
null,
() => {
res.json({
redirect: '/restricted',
anonWriteAccessDenied: true,
})
},
]
}
// Try to get the project, and/or an alternative action to take. // Try to get the project, and/or an alternative action to take.
// Returns a tuple of [project, action] // Returns a tuple of [project, action]
const project = await TokenAccessHandler.promises.getProjectByToken( const project = await TokenAccessHandler.promises.getProjectByToken(
@ -138,7 +160,6 @@ async function checkAndGetProjectOrResponseAction(
} }
const projectId = project._id const projectId = project._id
const isAnonymousUser = !userId
const tokenAccessEnabled = const tokenAccessEnabled =
TokenAccessHandler.tokenAccessEnabledForProject(project) TokenAccessHandler.tokenAccessEnabledForProject(project)
if (isAnonymousUser && tokenAccessEnabled) { if (isAnonymousUser && tokenAccessEnabled) {
@ -156,23 +177,10 @@ async function checkAndGetProjectOrResponseAction(
}, },
] ]
} else { } else {
logger.warn( // anonymous read-and-write token access should have been denied already
{ projectId }, throw new Error(
'[TokenAccess] deny anonymous read-and-write token access' 'unreachable: anonymous read-and-write token access bug'
) )
AuthenticationController.setRedirectInSession(
req,
TokenAccessHandler.makeTokenUrl(token)
)
return [
null,
() => {
res.json({
redirect: '/restricted',
anonWriteAccessDenied: true,
})
},
]
} }
} else if (tokenType === TokenAccessHandler.TOKEN_TYPES.READ_ONLY) { } else if (tokenType === TokenAccessHandler.TOKEN_TYPES.READ_ONLY) {
logger.debug({ projectId }, 'granting read-only anonymous access') logger.debug({ projectId }, 'granting read-only anonymous access')

View file

@ -993,6 +993,41 @@ describe('TokenAccess', function () {
done done
) )
}) })
it('should require login if project does not exist', function (done) {
async.series(
[
// delete project
cb => {
this.owner.deleteProject(this.projectId, cb)
},
cb =>
tryReadAndWriteTokenAccess(
this.anon,
this.tokens.readAndWrite,
(response, body) => {
expect(response.statusCode).to.equal(200)
},
(response, body) => {
expect(response.statusCode).to.equal(200)
expect(body).to.deep.equal({
redirect: '/restricted',
anonWriteAccessDenied: true,
})
},
cb
),
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()
}),
],
done
)
})
}) })
} else { } else {
describe('anonymous read-and-write token, enabled', function () { describe('anonymous read-and-write token, enabled', function () {
@ -1118,6 +1153,35 @@ describe('TokenAccess', function () {
) )
}) })
}) })
it('should 404 if project does not exist', function (done) {
async.series(
[
// delete project
cb => {
this.owner.deleteProject(this.projectId, cb)
},
cb =>
tryReadAndWriteTokenAccess(
this.anon,
this.tokens.readAndWrite,
(response, body) => {
expect(response.statusCode).to.equal(200)
},
(response, body) => {
expect(response.statusCode).to.equal(200)
expect(body).to.deep.equal({
v1Import: {
status: 'mustLogin',
},
})
},
cb
),
],
done
)
})
}) })
} }