Просмотр исходного кода

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

[real-time] add acceptance tests for token access

GitOrigin-RevId: fc0e174021ede19ef911a79a0978fb1db9171156
Jakob Ackermann 3 лет назад
Родитель
Сommit
ec66ba3573

+ 6 - 1
services/real-time/test/acceptance/js/ClientTrackingTests.js

@@ -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
             )

+ 78 - 23
services/real-time/test/acceptance/js/MatrixTests.js

@@ -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, [

+ 6 - 2
services/real-time/test/acceptance/js/helpers/FixturesManager.js

@@ -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,
           })
         }
       )

+ 9 - 2
services/real-time/test/acceptance/js/helpers/MockWebServer.js

@@ -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)