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

add missing token access fields to projects (#17372)

GitOrigin-RevId: d2eca00c40af65f0309f4b196fc3b5f043761729
ilkin-overleaf 2 лет назад
Родитель
Сommit
1c34a3fa68

+ 35 - 1
services/web/scripts/remove_deleted_users_from_token_access_refs.js

@@ -69,9 +69,11 @@ async function fixProjectsWithInvalidTokenAccessRefsIds(
   // get a set of all users ids as an in-memory cache
   const userIds = await findUserIds()
 
-  // default query for finding all projects with non-empty token access fields
+  // default query for finding all projects with non-existing/null or non-empty token access fields
   let query = {
     $or: [
+      { tokenAccessReadOnly_refs: { $not: { $type: 'array' } } },
+      { tokenAccessReadAndWrite_refs: { $not: { $type: 'array' } } },
       { 'tokenAccessReadOnly_refs.0': { $exists: true } },
       { 'tokenAccessReadAndWrite_refs.0': { $exists: true } },
     ],
@@ -91,6 +93,38 @@ async function fixProjectsWithInvalidTokenAccessRefsIds(
     query,
     async projects => {
       for (const project of projects) {
+        const isTokenAccessFieldMissing =
+          !project.tokenAccessReadOnly_refs ||
+          !project.tokenAccessReadAndWrite_refs
+        project.tokenAccessReadOnly_refs ??= []
+        project.tokenAccessReadAndWrite_refs ??= []
+
+        // update the token access fields if necessary
+        if (isTokenAccessFieldMissing) {
+          if (DRY_RUN) {
+            console.log(
+              `=> DRY RUN - would fix non-existing token access fields in project ${project._id.toString()}`
+            )
+          } else {
+            const fields = [
+              'tokenAccessReadOnly_refs',
+              'tokenAccessReadAndWrite_refs',
+            ]
+            for (const field of fields) {
+              await db.projects.updateOne(
+                {
+                  _id: project._id,
+                  [field]: { $not: { $type: 'array' } },
+                },
+                { $set: { [field]: [] } }
+              )
+            }
+            console.log(
+              `=> Fixed non-existing token access fields in project ${project._id.toString()}`
+            )
+          }
+        }
+
         // find the set of user ids that are in the token access fields
         // i.e. the set of collaborators
         const collaboratorIds = new Set()

+ 56 - 7
services/web/test/acceptance/src/RemoveDeletedUsersFromTokenAccessRefsTests.js

@@ -20,6 +20,7 @@ describe('RemoveDeletedUsersFromTokenAccessRefsTests', function () {
   const projectId1 = new ObjectId('65d726e807c024c8db43be22')
   const projectId2 = new ObjectId('65d726e807c024c8db43be23')
   const projectId3 = new ObjectId('65d726e807c024c8db43be24')
+  const projectId4 = new ObjectId('65d726e807c024c8db43be25')
 
   let insertedProjects
   beforeEach('insert projects', async function () {
@@ -37,7 +38,9 @@ describe('RemoveDeletedUsersFromTokenAccessRefsTests', function () {
       {
         _id: projectId3,
         tokenAccessReadAndWrite_refs: [userId3],
-        tokenAccessReadOnly_refs: [],
+      },
+      {
+        _id: projectId4,
       },
     ])
   })
@@ -96,6 +99,20 @@ describe('RemoveDeletedUsersFromTokenAccessRefsTests', function () {
       )
     })
 
+    it('should show projects with non-existing token access fields', function () {
+      expect(stdOut)
+        .to.match(
+          new RegExp(
+            `DRY RUN - would fix non-existing token access fields in project ${projectId3.toString()}`
+          )
+        )
+        .and.match(
+          new RegExp(
+            `DRY RUN - would fix non-existing token access fields in project ${projectId4.toString()}`
+          )
+        )
+    })
+
     it('should show the user ids (and their count) to be deleted', function () {
       expect(stdOut).to.match(
         new RegExp(
@@ -116,12 +133,25 @@ describe('RemoveDeletedUsersFromTokenAccessRefsTests', function () {
       const projects = await db.projects
         .find({}, { $sort: { _id: 1 } })
         .toArray()
-      const users = [userId1, userId2, userId3]
-      projects.forEach((project, i) => {
-        expect(project.tokenAccessReadAndWrite_refs[0].toString()).to.eq(
-          users[i].toString()
-        )
-      })
+      expect(projects).to.deep.equal([
+        {
+          _id: projectId1,
+          tokenAccessReadAndWrite_refs: [userId1],
+          tokenAccessReadOnly_refs: [],
+        },
+        {
+          _id: projectId2,
+          tokenAccessReadAndWrite_refs: [userId2],
+          tokenAccessReadOnly_refs: [],
+        },
+        {
+          _id: projectId3,
+          tokenAccessReadAndWrite_refs: [userId3],
+        },
+        {
+          _id: projectId4,
+        },
+      ])
     })
   })
 
@@ -154,6 +184,20 @@ describe('RemoveDeletedUsersFromTokenAccessRefsTests', function () {
       )
     })
 
+    it('should show fixed projects with non-existing token access fields', function () {
+      expect(stdOut)
+        .to.match(
+          new RegExp(
+            `Fixed non-existing token access fields in project ${projectId3.toString()}`
+          )
+        )
+        .and.match(
+          new RegExp(
+            `Fixed non-existing token access fields in project ${projectId4.toString()}`
+          )
+        )
+    })
+
     it('should show the deleted user ids (and their count) that were removed', function () {
       expect(stdOut).to.match(
         new RegExp(
@@ -185,6 +229,11 @@ describe('RemoveDeletedUsersFromTokenAccessRefsTests', function () {
           tokenAccessReadAndWrite_refs: [],
           tokenAccessReadOnly_refs: [],
         },
+        {
+          _id: projectId4,
+          tokenAccessReadOnly_refs: [],
+          tokenAccessReadAndWrite_refs: [],
+        },
       ])
     })
   })