From 281cedf1a28eb9dbf155b54f13a0bdae9b0c6ddb Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Wed, 19 Feb 2025 08:36:38 +0400 Subject: [PATCH] fix: updated migration to support additional privileges --- ...kfill-secret-permissions-with-readvalue.ts | 120 +++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/backend/src/db/migrations/20250218020306_backfill-secret-permissions-with-readvalue.ts b/backend/src/db/migrations/20250218020306_backfill-secret-permissions-with-readvalue.ts index b29c2901b..c672a1a7d 100644 --- a/backend/src/db/migrations/20250218020306_backfill-secret-permissions-with-readvalue.ts +++ b/backend/src/db/migrations/20250218020306_backfill-secret-permissions-with-readvalue.ts @@ -31,6 +31,12 @@ export const unpackPermissions = (permissions: unknown) => export async function up(knex: Knex): Promise { const projectRoles = await knex(TableName.ProjectRoles).select(selectAllTableCols(TableName.ProjectRoles)); + const projectIdentityAdditionalPrivileges = await knex(TableName.IdentityProjectAdditionalPrivilege).select( + selectAllTableCols(TableName.IdentityProjectAdditionalPrivilege) + ); + const projectUserAdditionalPrivileges = await knex(TableName.ProjectUserAdditionalPrivilege).select( + selectAllTableCols(TableName.ProjectUserAdditionalPrivilege) + ); for await (const projectRole of projectRoles) { const { permissions } = projectRole; @@ -59,10 +65,72 @@ export async function up(knex: Knex): Promise { .update({ permissions: JSON.stringify(repackedPermissions) }); } } + + for await (const identityAdditionalPrivilege of projectIdentityAdditionalPrivileges) { + const { permissions } = identityAdditionalPrivilege; + + const parsedPermissions = unpackPermissions(permissions); + let shouldUpdate = false; + + for (let i = 0; i < parsedPermissions.length; i += 1) { + const parsedPermission = parsedPermissions[i]; + const { subject, action } = parsedPermission; + + if (subject === ProjectPermissionSub.Secrets) { + if (action.includes(SecretActions.Read) && !action.includes(SecretActions.ReadValue)) { + action.push(SecretActions.ReadValue); + parsedPermissions[i] = { ...parsedPermission, action }; + shouldUpdate = true; + } + } + } + + if (shouldUpdate) { + const repackedPermissions = packRules(parsedPermissions); + + await knex(TableName.IdentityProjectAdditionalPrivilege) + .where("id", identityAdditionalPrivilege.id) + .update({ permissions: JSON.stringify(repackedPermissions) }); + } + } + + for await (const userAdditionalPrivilege of projectUserAdditionalPrivileges) { + const { permissions } = userAdditionalPrivilege; + + const parsedPermissions = unpackPermissions(permissions); + let shouldUpdate = false; + + for (let i = 0; i < parsedPermissions.length; i += 1) { + const parsedPermission = parsedPermissions[i]; + const { subject, action } = parsedPermission; + + if (subject === ProjectPermissionSub.Secrets) { + if (action.includes(SecretActions.Read) && !action.includes(SecretActions.ReadValue)) { + action.push(SecretActions.ReadValue); + parsedPermissions[i] = { ...parsedPermission, action }; + shouldUpdate = true; + } + } + } + + if (shouldUpdate) { + const repackedPermissions = packRules(parsedPermissions); + + await knex(TableName.ProjectUserAdditionalPrivilege) + .where("id", userAdditionalPrivilege.id) + .update({ permissions: JSON.stringify(repackedPermissions) }); + } + } } export async function down(knex: Knex): Promise { const projectRoles = await knex(TableName.ProjectRoles).select(selectAllTableCols(TableName.ProjectRoles)); + const identityAdditionalPrivileges = await knex(TableName.IdentityProjectAdditionalPrivilege).select( + selectAllTableCols(TableName.IdentityProjectAdditionalPrivilege) + ); + const userAdditionalPrivileges = await knex(TableName.ProjectUserAdditionalPrivilege).select( + selectAllTableCols(TableName.ProjectUserAdditionalPrivilege) + ); for await (const projectRole of projectRoles) { const { permissions } = projectRole; @@ -76,7 +144,7 @@ export async function down(knex: Knex): Promise { if (subject === ProjectPermissionSub.Secrets) { if (action.includes(SecretActions.ReadValue)) { - action.splice(action.indexOf(SecretActions.ReadValue), 1); + action.splice(action.indexOf(SecretActions.ReadValue)); parsedPermissions[i] = { ...parsedPermission, action }; } } @@ -88,4 +156,54 @@ export async function down(knex: Knex): Promise { .where("id", projectRole.id) .update({ permissions: JSON.stringify(repackedPermissions) }); } + + for await (const identityAdditionalPrivilege of identityAdditionalPrivileges) { + const { permissions } = identityAdditionalPrivilege; + + const parsedPermissions = unpackPermissions(permissions); + + for (let i = 0; i < parsedPermissions.length; i += 1) { + const parsedPermission = parsedPermissions[i]; + + const { subject, action } = parsedPermission; + + if (subject === ProjectPermissionSub.Secrets) { + if (action.includes(SecretActions.ReadValue)) { + action.splice(action.indexOf(SecretActions.ReadValue)); + parsedPermissions[i] = { ...parsedPermission, action }; + } + } + } + + const repackedPermissions = packRules(parsedPermissions); + + await knex(TableName.IdentityProjectAdditionalPrivilege) + .where("id", identityAdditionalPrivilege.id) + .update({ permissions: JSON.stringify(repackedPermissions) }); + } + + for await (const userAdditionalPrivilege of userAdditionalPrivileges) { + const { permissions } = userAdditionalPrivilege; + + const parsedPermissions = unpackPermissions(permissions); + + for (let i = 0; i < parsedPermissions.length; i += 1) { + const parsedPermission = parsedPermissions[i]; + + const { subject, action } = parsedPermission; + + if (subject === ProjectPermissionSub.Secrets) { + if (action.includes(SecretActions.ReadValue)) { + action.splice(action.indexOf(SecretActions.ReadValue)); + parsedPermissions[i] = { ...parsedPermission, action }; + } + } + } + + const repackedPermissions = packRules(parsedPermissions); + + await knex(TableName.ProjectUserAdditionalPrivilege) + .where("id", userAdditionalPrivilege.id) + .update({ permissions: JSON.stringify(repackedPermissions) }); + } }