From d10f0256036852a9dda1d5abd1b209ce93719783 Mon Sep 17 00:00:00 2001 From: ilkin-overleaf <100852799+ilkin-overleaf@users.noreply.github.com> Date: Wed, 6 Mar 2024 11:21:46 +0200 Subject: [PATCH] add missing token access fields to projects (#17372) GitOrigin-RevId: d2eca00c40af65f0309f4b196fc3b5f043761729 --- ...ve_deleted_users_from_token_access_refs.js | 36 ++++++++++- ...oveDeletedUsersFromTokenAccessRefsTests.js | 63 ++++++++++++++++--- 2 files changed, 91 insertions(+), 8 deletions(-) diff --git a/services/web/scripts/remove_deleted_users_from_token_access_refs.js b/services/web/scripts/remove_deleted_users_from_token_access_refs.js index eeb7454344..4f078dfbb0 100644 --- a/services/web/scripts/remove_deleted_users_from_token_access_refs.js +++ b/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() diff --git a/services/web/test/acceptance/src/RemoveDeletedUsersFromTokenAccessRefsTests.js b/services/web/test/acceptance/src/RemoveDeletedUsersFromTokenAccessRefsTests.js index ef8aa5d7e9..5c2b4180ea 100644 --- a/services/web/test/acceptance/src/RemoveDeletedUsersFromTokenAccessRefsTests.js +++ b/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: [], + }, ]) }) })