From 0743fe4a7645a56813530da0228a2ff6fb4f2d8f Mon Sep 17 00:00:00 2001 From: Sven Efftinge Date: Tue, 7 May 2024 10:28:45 +0200 Subject: [PATCH] [server] delete project env vars (#19707) --- components/gitpod-db/src/tables.ts | 6 ------ ...715064681193-DeleteDanglingProjectEnvVars.ts | 17 +++++++++++++++++ .../gitpod-db/src/typeorm/project-db-impl.ts | 7 +------ .../src/projects/projects-service.spec.db.ts | 12 ++++++++++++ .../server/src/projects/projects-service.ts | 6 ++++++ 5 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 components/gitpod-db/src/typeorm/migration/1715064681193-DeleteDanglingProjectEnvVars.ts diff --git a/components/gitpod-db/src/tables.ts b/components/gitpod-db/src/tables.ts index 0309f7c2e48707..3873b1e97cd009 100644 --- a/components/gitpod-db/src/tables.ts +++ b/components/gitpod-db/src/tables.ts @@ -74,12 +74,6 @@ export class GitpodTableDescriptionProvider implements TableDescriptionProvider deletionColumn: "deleted", timeColumn: "_lastModified", }, - { - name: "d_b_project_env_var", - primaryKeys: ["id", "projectId"], - deletionColumn: "deleted", - timeColumn: "_lastModified", - }, { name: "d_b_project_info", primaryKeys: ["projectId"], diff --git a/components/gitpod-db/src/typeorm/migration/1715064681193-DeleteDanglingProjectEnvVars.ts b/components/gitpod-db/src/typeorm/migration/1715064681193-DeleteDanglingProjectEnvVars.ts new file mode 100644 index 00000000000000..9246181746a176 --- /dev/null +++ b/components/gitpod-db/src/typeorm/migration/1715064681193-DeleteDanglingProjectEnvVars.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2024 Gitpod GmbH. All rights reserved. + * Licensed under the GNU Affero General Public License (AGPL). + * See License.AGPL.txt in the project root for license information. + */ + +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class DeleteDanglingProjectEnvVars1715064681193 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + "DELETE FROM d_b_project_env_var WHERE projectId IN (SELECT id FROM d_b_project WHERE markedDeleted=true)", + ); + } + + public async down(queryRunner: QueryRunner): Promise {} +} diff --git a/components/gitpod-db/src/typeorm/project-db-impl.ts b/components/gitpod-db/src/typeorm/project-db-impl.ts index ffb3fa1209da55..475bf9700de99b 100644 --- a/components/gitpod-db/src/typeorm/project-db-impl.ts +++ b/components/gitpod-db/src/typeorm/project-db-impl.ts @@ -223,12 +223,7 @@ export class ProjectDBImpl extends TransactionalDBImpl implements Pro public async deleteProjectEnvironmentVariable(variableId: string): Promise { const envVarRepo = await this.getProjectEnvVarRepo(); - const envVarWithValue = await envVarRepo.findOne({ id: variableId, deleted: false }); - if (!envVarWithValue) { - throw new Error("A environment variable with this name could not be found for this project"); - } - envVarWithValue.deleted = true; - await envVarRepo.update({ id: envVarWithValue.id, projectId: envVarWithValue.projectId }, envVarWithValue); + await envVarRepo.delete({ id: variableId }); } public async getProjectEnvironmentVariableValues(envVars: ProjectEnvVar[]): Promise { diff --git a/components/server/src/projects/projects-service.spec.db.ts b/components/server/src/projects/projects-service.spec.db.ts index 326ecf095cbe03..abc03b6295830b 100644 --- a/components/server/src/projects/projects-service.spec.db.ts +++ b/components/server/src/projects/projects-service.spec.db.ts @@ -18,6 +18,7 @@ import { createTestContainer, withTestCtx } from "../test/service-testing-contai import { OldProjectSettings, ProjectsService } from "./projects-service"; import { daysBefore } from "@gitpod/gitpod-protocol/lib/util/timeutil"; import { SYSTEM_USER } from "../authorization/authorizer"; +import { EnvVarService } from "../user/env-var-service"; const expect = chai.expect; @@ -99,11 +100,22 @@ describe("ProjectsService", async () => { it("should deleteProject", async () => { const ps = container.get(ProjectsService); + const evs = container.get(EnvVarService); + const pdb = container.get(ProjectDB); const project1 = await createTestProject(ps, org, owner); + await evs.addProjectEnvVar(member.id, project1.id, { + name: "key", + value: "value", + censored: false, + }); + + expect(await pdb.getProjectEnvironmentVariables(project1.id)).to.have.lengthOf(1); await ps.deleteProject(member.id, project1.id); let projects = await ps.getProjects(member.id, org.id); expect(projects.length).to.equal(0); + // have to use db directly to verify the env vars are really deleted, the env var service would throw with project not found. + expect(await pdb.getProjectEnvironmentVariables(project1.id)).to.have.lengthOf(0); const project2 = await createTestProject(ps, org, owner); await expectError(ErrorCodes.NOT_FOUND, () => ps.deleteProject(stranger.id, project2.id)); diff --git a/components/server/src/projects/projects-service.ts b/components/server/src/projects/projects-service.ts index 72c6bfc4d9b6f4..e465ffbd3ee9f5 100644 --- a/components/server/src/projects/projects-service.ts +++ b/components/server/src/projects/projects-service.ts @@ -320,6 +320,12 @@ export class ProjectsService { orgId = project.teamId; await db.markDeleted(projectId); + // delete env vars + const envVars = await db.getProjectEnvironmentVariables(projectId); + for (const envVar of envVars) { + await db.deleteProjectEnvironmentVariable(envVar.id); + } + await this.auth.removeProjectFromOrg(userId, orgId, projectId); }); this.analytics.track({