Skip to content

Commit

Permalink
Clean up SCM connections of installation admin (#19601)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexTugarev authored Apr 5, 2024
1 parent 949af13 commit d38b01c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
9 changes: 8 additions & 1 deletion components/server/src/auth/authenticator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* See License.AGPL.txt in the project root for license information.
*/

import { TeamDB } from "@gitpod/gitpod-db/lib";
import { BUILTIN_INSTLLATION_ADMIN_USER_ID, TeamDB } from "@gitpod/gitpod-db/lib";
import { User } from "@gitpod/gitpod-protocol";
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
import express from "express";
Expand Down Expand Up @@ -221,6 +221,13 @@ export class Authenticator {
res.redirect(this.getSorryUrl(`Not authenticated. Please login.`));
return;
}
if (user.id === BUILTIN_INSTLLATION_ADMIN_USER_ID) {
log.info(`Authorization is not permitted for admin user.`);
res.redirect(
this.getSorryUrl(`Authorization is not permitted for admin user. Please login with a user account.`),
);
return;
}
const returnTo: string | undefined = req.query.returnTo?.toString();
const host: string | undefined = req.query.host?.toString();
const scopes: string = req.query.scopes?.toString() || "";
Expand Down
2 changes: 2 additions & 0 deletions components/server/src/container-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ import { ScmService } from "./scm/scm-service";
import { ContextService } from "./workspace/context-service";
import { RateLimitter } from "./rate-limitter";
import { AnalyticsController } from "./analytics-controller";
import { InstallationAdminCleanup } from "./jobs/installation-admin-cleanup";

export const productionContainerModule = new ContainerModule(
(bind, unbind, isBound, rebind, unbindAsync, onActivation, onDeactivation) => {
Expand Down Expand Up @@ -371,6 +372,7 @@ export const productionContainerModule = new ContainerModule(
bind(SnapshotsJob).toSelf().inSingletonScope();
bind(JobRunner).toSelf().inSingletonScope();
bind(RelationshipUpdateJob).toSelf().inSingletonScope();
bind(InstallationAdminCleanup).toSelf().inSingletonScope();

// Redis
bind(Redis).toDynamicValue((ctx) => {
Expand Down
41 changes: 41 additions & 0 deletions components/server/src/jobs/installation-admin-cleanup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* 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 { BUILTIN_INSTLLATION_ADMIN_USER_ID, UserDB } from "@gitpod/gitpod-db/lib";
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
import { inject, injectable } from "inversify";
import { Job } from "./runner";

@injectable()
export class InstallationAdminCleanup implements Job {
@inject(UserDB) protected readonly userDb: UserDB;

public name = "installation-admin-cleanup";
public frequencyMs = 5 * 60 * 1000; // every 5 minutes

public async run(): Promise<void> {
try {
const installationAdmin = await this.userDb.findUserById(BUILTIN_INSTLLATION_ADMIN_USER_ID);
if (!installationAdmin) {
return;
}

let cleanupRequired = false;
for (const identity of installationAdmin.identities) {
cleanupRequired = true;
identity.deleted = true;
await this.userDb.deleteTokens(identity);
}
if (cleanupRequired) {
await this.userDb.storeUser(installationAdmin);
log.info("Cleaned up SCM connections of installation admin.");
}
} catch (err) {
log.error("Failed to clean up SCM connections of installation admin.", err);
throw err;
}
}
}
3 changes: 3 additions & 0 deletions components/server/src/jobs/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { RelationshipUpdateJob } from "../authorization/relationship-updater-job
import { WorkspaceStartController } from "../workspace/workspace-start-controller";
import { runWithRequestContext } from "../util/request-context";
import { SYSTEM_USER } from "../authorization/authorizer";
import { InstallationAdminCleanup } from "./installation-admin-cleanup";

export const Job = Symbol("Job");

Expand All @@ -42,6 +43,7 @@ export class JobRunner {
@inject(SnapshotsJob) private readonly snapshotsJob: SnapshotsJob,
@inject(RelationshipUpdateJob) private readonly relationshipUpdateJob: RelationshipUpdateJob,
@inject(WorkspaceStartController) private readonly workspaceStartController: WorkspaceStartController,
@inject(InstallationAdminCleanup) private readonly installationAdminCleanup: InstallationAdminCleanup,
) {}

public start(): DisposableCollection {
Expand All @@ -56,6 +58,7 @@ export class JobRunner {
this.snapshotsJob,
this.relationshipUpdateJob,
this.workspaceStartController,
this.installationAdminCleanup,
];

for (const job of jobs) {
Expand Down

0 comments on commit d38b01c

Please sign in to comment.