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-06-13 09:35:39 +01:00 committed by Copybot
parent 2e77d4ab65
commit ec66ba3573
4 changed files with 99 additions and 28 deletions

View file

@ -154,10 +154,14 @@ describe('clientTracking', function () {
project: { name: 'Test Project' },
publicAccess: 'readAndWrite',
},
(error, { user_id: userId, project_id: projectId }) => {
(
error,
{ user_id: userId, project_id: projectId, anonymousAccessToken }
) => {
if (error) return done(error)
this.user_id = userId
this.project_id = projectId
this.anonymousAccessToken = anonymousAccessToken
return cb()
}
)
@ -203,6 +207,7 @@ describe('clientTracking', function () {
'joinProject',
{
project_id: this.project_id,
anonymousAccessToken: this.anonymousAccessToken,
},
cb
)

View file

@ -50,6 +50,7 @@ const async = require('async')
const RealTimeClient = require('./helpers/RealTimeClient')
const FixturesManager = require('./helpers/FixturesManager')
const MockWebServer = require('./helpers/MockWebServer')
const settings = require('@overleaf/settings')
const Keys = settings.redis.documentupdater.key_schema
@ -64,12 +65,16 @@ function cleanupPreviousUpdates(docId, cb) {
}
describe('MatrixTests', function () {
let privateProjectId, privateDocId, readWriteProjectId, readWriteDocId
let privateProjectId,
privateDocId,
readWriteProjectId,
readWriteDocId,
readWriteAnonymousAccessToken
let privateClient
before(function setupPrivateProject(done) {
FixturesManager.setUpEditorSession(
{ privilegeLevel: 'owner' },
{ privilegeLevel: 'owner', publicAccessLevel: 'readAndWrite' },
(err, { project_id: projectId, doc_id: docId }) => {
if (err) return done(err)
privateProjectId = projectId
@ -94,9 +99,10 @@ describe('MatrixTests', function () {
{
publicAccess: 'readAndWrite',
},
(err, { project_id: projectId, doc_id: docId }) => {
(err, { project_id: projectId, doc_id: docId, anonymousAccessToken }) => {
readWriteProjectId = projectId
readWriteDocId = docId
readWriteAnonymousAccessToken = anonymousAccessToken
done(err)
}
)
@ -104,31 +110,19 @@ describe('MatrixTests', function () {
const USER_SETUP = {
anonymous: {
setup(cb) {
RealTimeClient.setSession({}, err => {
if (err) return cb(err)
cb(null, {
client: RealTimeClient.connect(),
})
})
getAnonymousAccessToken() {
return readWriteAnonymousAccessToken
},
},
registered: {
setup(cb) {
const userId = FixturesManager.getRandomId()
RealTimeClient.setSession(
{
user: {
_id: userId,
first_name: 'Joe',
last_name: 'Bloggs',
anonTokenAccess: {
[readWriteProjectId]: readWriteAnonymousAccessToken,
},
},
err => {
if (err) return cb(err)
cb(null, {
user_id: userId,
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: {
getAnonymousAccessToken() {},
setup(cb) {
FixturesManager.setUpEditorSession(
{ privilegeLevel: 'owner' },
(err, { project_id: projectId, user_id: userId, doc_id: docId }) => {
if (err) return cb(err)
MockWebServer.inviteUserToProject(
readWriteProjectId,
{ _id: userId },
'readAndWrite'
)
cb(null, {
user_id: userId,
project_id: projectId,
@ -169,8 +191,12 @@ describe('MatrixTests', function () {
joinReadWriteProject: {
getActions(cb) {
const anonymousAccessToken = userItem.getAnonymousAccessToken()
cb(null, [
{ rpc: 'joinProject', args: [{ project_id: readWriteProjectId }] },
{
rpc: 'joinProject',
args: [{ project_id: readWriteProjectId, anonymousAccessToken }],
},
])
},
needsOwnProject: false,
@ -178,8 +204,12 @@ describe('MatrixTests', function () {
joinReadWriteProjectAndDoc: {
getActions(cb) {
const anonymousAccessToken = userItem.getAnonymousAccessToken()
cb(null, [
{ rpc: 'joinProject', args: [{ project_id: readWriteProjectId }] },
{
rpc: 'joinProject',
args: [{ project_id: readWriteProjectId, anonymousAccessToken }],
},
{ rpc: 'joinDoc', args: [readWriteDocId] },
])
},
@ -188,8 +218,12 @@ describe('MatrixTests', function () {
joinOwnProject: {
getActions(cb) {
const anonymousAccessToken = userItem.getAnonymousAccessToken()
cb(null, [
{ rpc: 'joinProject', args: [{ project_id: options.project_id }] },
{
rpc: 'joinProject',
args: [{ project_id: options.project_id, anonymousAccessToken }],
},
])
},
needsOwnProject: true,
@ -197,8 +231,12 @@ describe('MatrixTests', function () {
joinOwnProjectAndDoc: {
getActions(cb) {
const anonymousAccessToken = userItem.getAnonymousAccessToken()
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] },
])
},
@ -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: {
getActions(cb) {
cb(null, [

View file

@ -28,19 +28,22 @@ module.exports = FixturesManager = {
if (!options.project) {
options.project = { name: 'Test Project' }
}
const {
let {
project_id: projectId,
user_id: userId,
privilegeLevel,
project,
publicAccess,
userMetadata,
anonymousAccessToken,
} = options
const privileges = {}
privileges[userId] = privilegeLevel
if (publicAccess) {
privileges['anonymous-user'] = publicAccess
anonymousAccessToken =
anonymousAccessToken || FixturesManager.getRandomId()
privileges[anonymousAccessToken] = publicAccess
}
const metadataByUser = {}
@ -73,6 +76,7 @@ module.exports = FixturesManager = {
user_id: userId,
privilegeLevel,
project,
anonymousAccessToken,
})
}
)

View file

@ -24,14 +24,19 @@ module.exports = MockWebServer = {
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) {
callback = function () {}
}
const project = MockWebServer.projects[projectId]
const privilegeLevel =
MockWebServer.privileges[projectId][userId] ||
MockWebServer.privileges[projectId]['anonymous-user']
MockWebServer.privileges[projectId][anonymousAccessToken]
const userMetadata = MockWebServer.userMetadata[projectId]?.[userId]
if (privilegeLevel === 'owner') {
project.owner = { _id: userId }
@ -44,6 +49,7 @@ module.exports = MockWebServer = {
joinProjectRequest(req, res, next) {
const { project_id: projectId } = req.params
const { user_id: userId } = req.query
const { 'x-sl-anonymous-access-token': anonymousAccessToken } = req.headers
if (projectId === '404404404404404404404404') {
// not-found
return res.status(404).send()
@ -59,6 +65,7 @@ module.exports = MockWebServer = {
return MockWebServer.joinProject(
projectId,
userId,
anonymousAccessToken,
(error, project, privilegeLevel, userMetadata) => {
if (error != null) {
return next(error)