Merge pull request #13442 from overleaf/jpa-real-time-anonymous-access-tests

[real-time] add acceptance tests for token access

GitOrigin-RevId: fc0e174021ede19ef911a79a0978fb1db9171156
This commit is contained in:
Jakob Ackermann
2023-07-17 10:33:08 +00:00
committed by Copybot
parent 4c302c754f
commit 21444b9d02
4 changed files with 99 additions and 28 deletions
@@ -154,10 +154,14 @@ describe('clientTracking', function () {
project: { name: 'Test Project' }, project: { name: 'Test Project' },
publicAccess: 'readAndWrite', publicAccess: 'readAndWrite',
}, },
(error, { user_id: userId, project_id: projectId }) => { (
error,
{ user_id: userId, project_id: projectId, anonymousAccessToken }
) => {
if (error) return done(error) if (error) return done(error)
this.user_id = userId this.user_id = userId
this.project_id = projectId this.project_id = projectId
this.anonymousAccessToken = anonymousAccessToken
return cb() return cb()
} }
) )
@@ -203,6 +207,7 @@ describe('clientTracking', function () {
'joinProject', 'joinProject',
{ {
project_id: this.project_id, project_id: this.project_id,
anonymousAccessToken: this.anonymousAccessToken,
}, },
cb cb
) )
@@ -50,6 +50,7 @@ const async = require('async')
const RealTimeClient = require('./helpers/RealTimeClient') const RealTimeClient = require('./helpers/RealTimeClient')
const FixturesManager = require('./helpers/FixturesManager') const FixturesManager = require('./helpers/FixturesManager')
const MockWebServer = require('./helpers/MockWebServer')
const settings = require('@overleaf/settings') const settings = require('@overleaf/settings')
const Keys = settings.redis.documentupdater.key_schema const Keys = settings.redis.documentupdater.key_schema
@@ -64,12 +65,16 @@ function cleanupPreviousUpdates(docId, cb) {
} }
describe('MatrixTests', function () { describe('MatrixTests', function () {
let privateProjectId, privateDocId, readWriteProjectId, readWriteDocId let privateProjectId,
privateDocId,
readWriteProjectId,
readWriteDocId,
readWriteAnonymousAccessToken
let privateClient let privateClient
before(function setupPrivateProject(done) { before(function setupPrivateProject(done) {
FixturesManager.setUpEditorSession( FixturesManager.setUpEditorSession(
{ privilegeLevel: 'owner' }, { privilegeLevel: 'owner', publicAccessLevel: 'readAndWrite' },
(err, { project_id: projectId, doc_id: docId }) => { (err, { project_id: projectId, doc_id: docId }) => {
if (err) return done(err) if (err) return done(err)
privateProjectId = projectId privateProjectId = projectId
@@ -94,9 +99,10 @@ describe('MatrixTests', function () {
{ {
publicAccess: 'readAndWrite', publicAccess: 'readAndWrite',
}, },
(err, { project_id: projectId, doc_id: docId }) => { (err, { project_id: projectId, doc_id: docId, anonymousAccessToken }) => {
readWriteProjectId = projectId readWriteProjectId = projectId
readWriteDocId = docId readWriteDocId = docId
readWriteAnonymousAccessToken = anonymousAccessToken
done(err) done(err)
} }
) )
@@ -104,31 +110,19 @@ describe('MatrixTests', function () {
const USER_SETUP = { const USER_SETUP = {
anonymous: { anonymous: {
setup(cb) { getAnonymousAccessToken() {
RealTimeClient.setSession({}, err => { return readWriteAnonymousAccessToken
if (err) return cb(err)
cb(null, {
client: RealTimeClient.connect(),
})
})
}, },
},
registered: {
setup(cb) { setup(cb) {
const userId = FixturesManager.getRandomId()
RealTimeClient.setSession( RealTimeClient.setSession(
{ {
user: { anonTokenAccess: {
_id: userId, [readWriteProjectId]: readWriteAnonymousAccessToken,
first_name: 'Joe',
last_name: 'Bloggs',
}, },
}, },
err => { err => {
if (err) return cb(err) if (err) return cb(err)
cb(null, { cb(null, {
user_id: userId,
client: RealTimeClient.connect(), client: RealTimeClient.connect(),
}) })
} }
@@ -136,12 +130,40 @@ describe('MatrixTests', function () {
}, },
}, },
registered: {
getAnonymousAccessToken() {},
setup(cb) {
const userId = FixturesManager.getRandomId()
const user = { _id: userId, first_name: 'Joe', last_name: 'Bloggs' }
RealTimeClient.setSession({ user }, err => {
if (err) return cb(err)
MockWebServer.inviteUserToProject(
readWriteProjectId,
user,
'readAndWrite'
)
cb(null, {
user_id: userId,
client: RealTimeClient.connect(),
})
})
},
},
registeredWithOwnedProject: { registeredWithOwnedProject: {
getAnonymousAccessToken() {},
setup(cb) { setup(cb) {
FixturesManager.setUpEditorSession( FixturesManager.setUpEditorSession(
{ privilegeLevel: 'owner' }, { privilegeLevel: 'owner' },
(err, { project_id: projectId, user_id: userId, doc_id: docId }) => { (err, { project_id: projectId, user_id: userId, doc_id: docId }) => {
if (err) return cb(err) if (err) return cb(err)
MockWebServer.inviteUserToProject(
readWriteProjectId,
{ _id: userId },
'readAndWrite'
)
cb(null, { cb(null, {
user_id: userId, user_id: userId,
project_id: projectId, project_id: projectId,
@@ -169,8 +191,12 @@ describe('MatrixTests', function () {
joinReadWriteProject: { joinReadWriteProject: {
getActions(cb) { getActions(cb) {
const anonymousAccessToken = userItem.getAnonymousAccessToken()
cb(null, [ cb(null, [
{ rpc: 'joinProject', args: [{ project_id: readWriteProjectId }] }, {
rpc: 'joinProject',
args: [{ project_id: readWriteProjectId, anonymousAccessToken }],
},
]) ])
}, },
needsOwnProject: false, needsOwnProject: false,
@@ -178,8 +204,12 @@ describe('MatrixTests', function () {
joinReadWriteProjectAndDoc: { joinReadWriteProjectAndDoc: {
getActions(cb) { getActions(cb) {
const anonymousAccessToken = userItem.getAnonymousAccessToken()
cb(null, [ cb(null, [
{ rpc: 'joinProject', args: [{ project_id: readWriteProjectId }] }, {
rpc: 'joinProject',
args: [{ project_id: readWriteProjectId, anonymousAccessToken }],
},
{ rpc: 'joinDoc', args: [readWriteDocId] }, { rpc: 'joinDoc', args: [readWriteDocId] },
]) ])
}, },
@@ -188,8 +218,12 @@ describe('MatrixTests', function () {
joinOwnProject: { joinOwnProject: {
getActions(cb) { getActions(cb) {
const anonymousAccessToken = userItem.getAnonymousAccessToken()
cb(null, [ cb(null, [
{ rpc: 'joinProject', args: [{ project_id: options.project_id }] }, {
rpc: 'joinProject',
args: [{ project_id: options.project_id, anonymousAccessToken }],
},
]) ])
}, },
needsOwnProject: true, needsOwnProject: true,
@@ -197,8 +231,12 @@ describe('MatrixTests', function () {
joinOwnProjectAndDoc: { joinOwnProjectAndDoc: {
getActions(cb) { getActions(cb) {
const anonymousAccessToken = userItem.getAnonymousAccessToken()
cb(null, [ cb(null, [
{ rpc: 'joinProject', args: [{ project_id: options.project_id }] }, {
rpc: 'joinProject',
args: [{ project_id: options.project_id, anonymousAccessToken }],
},
{ rpc: 'joinDoc', args: [options.doc_id] }, { rpc: 'joinDoc', args: [options.doc_id] },
]) ])
}, },
@@ -252,6 +290,23 @@ describe('MatrixTests', function () {
}, },
}, },
joinProjectWithBadAccessToken: {
getActions(cb) {
cb(null, [
{
rpc: 'joinProject',
args: [
{
project_id: privateProjectId,
anonymousAccessToken: 'invalid-access-token',
},
],
fails: 1,
},
])
},
},
joinProjectWithDocId: { joinProjectWithDocId: {
getActions(cb) { getActions(cb) {
cb(null, [ cb(null, [
@@ -28,19 +28,22 @@ module.exports = FixturesManager = {
if (!options.project) { if (!options.project) {
options.project = { name: 'Test Project' } options.project = { name: 'Test Project' }
} }
const { let {
project_id: projectId, project_id: projectId,
user_id: userId, user_id: userId,
privilegeLevel, privilegeLevel,
project, project,
publicAccess, publicAccess,
userMetadata, userMetadata,
anonymousAccessToken,
} = options } = options
const privileges = {} const privileges = {}
privileges[userId] = privilegeLevel privileges[userId] = privilegeLevel
if (publicAccess) { if (publicAccess) {
privileges['anonymous-user'] = publicAccess anonymousAccessToken =
anonymousAccessToken || FixturesManager.getRandomId()
privileges[anonymousAccessToken] = publicAccess
} }
const metadataByUser = {} const metadataByUser = {}
@@ -73,6 +76,7 @@ module.exports = FixturesManager = {
user_id: userId, user_id: userId,
privilegeLevel, privilegeLevel,
project, project,
anonymousAccessToken,
}) })
} }
) )
@@ -24,14 +24,19 @@ module.exports = MockWebServer = {
return (MockWebServer.projects[projectId] = project) return (MockWebServer.projects[projectId] = project)
}, },
joinProject(projectId, userId, callback) { inviteUserToProject(projectId, user, privileges) {
MockWebServer.privileges[projectId][user._id] = privileges
MockWebServer.userMetadata[projectId][user._id] = user
},
joinProject(projectId, userId, anonymousAccessToken, callback) {
if (callback == null) { if (callback == null) {
callback = function () {} callback = function () {}
} }
const project = MockWebServer.projects[projectId] const project = MockWebServer.projects[projectId]
const privilegeLevel = const privilegeLevel =
MockWebServer.privileges[projectId][userId] || MockWebServer.privileges[projectId][userId] ||
MockWebServer.privileges[projectId]['anonymous-user'] MockWebServer.privileges[projectId][anonymousAccessToken]
const userMetadata = MockWebServer.userMetadata[projectId]?.[userId] const userMetadata = MockWebServer.userMetadata[projectId]?.[userId]
if (privilegeLevel === 'owner') { if (privilegeLevel === 'owner') {
project.owner = { _id: userId } project.owner = { _id: userId }
@@ -44,6 +49,7 @@ module.exports = MockWebServer = {
joinProjectRequest(req, res, next) { joinProjectRequest(req, res, next) {
const { project_id: projectId } = req.params const { project_id: projectId } = req.params
const { user_id: userId } = req.query const { user_id: userId } = req.query
const { 'x-sl-anonymous-access-token': anonymousAccessToken } = req.headers
if (projectId === '404404404404404404404404') { if (projectId === '404404404404404404404404') {
// not-found // not-found
return res.status(404).send() return res.status(404).send()
@@ -59,6 +65,7 @@ module.exports = MockWebServer = {
return MockWebServer.joinProject( return MockWebServer.joinProject(
projectId, projectId,
userId, userId,
anonymousAccessToken,
(error, project, privilegeLevel, userMetadata) => { (error, project, privilegeLevel, userMetadata) => {
if (error != null) { if (error != null) {
return next(error) return next(error)