Skip to content

Commit bf39da2

Browse files
geroplakosyakov
authored andcommitted
wip
1 parent b43c266 commit bf39da2

File tree

4 files changed

+73
-62
lines changed

4 files changed

+73
-62
lines changed

components/server/src/api/user.spec.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { suite, test } from "@testdeck/mocha";
88
import { APIUserService } from "./user";
99
import { Container } from "inversify";
1010
import { testContainer } from "@gitpod/gitpod-db/lib";
11-
import { WorkspaceStarter } from "../workspace/workspace-starter";
1211
import { UserAuthentication } from "../user/user-authentication";
1312
import { BlockUserRequest, BlockUserResponse } from "@gitpod/public-api/lib/gitpod/experimental/v1/user_pb";
1413
import { User } from "@gitpod/gitpod-protocol";
@@ -18,22 +17,24 @@ import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing";
1817
import { v4 as uuidv4 } from "uuid";
1918
import { ConnectError, Code } from "@bufbuild/connect";
2019
import * as chai from "chai";
20+
import { WorkspaceService } from "../workspace/workspace-service";
2121

2222
const expect = chai.expect;
2323

2424
@suite()
2525
export class APIUserServiceSpec {
2626
private container: Container;
27-
private workspaceStarterMock: WorkspaceStarter = {
27+
private workspaceStarterMock: WorkspaceService = {
2828
stopRunningWorkspacesForUser: async (
2929
ctx: TraceContext,
30-
userID: string,
30+
userId: string,
31+
userIdToStop: string,
3132
reason: string,
3233
policy?: StopWorkspacePolicy,
3334
): Promise<Workspace[]> => {
3435
return [];
3536
},
36-
} as WorkspaceStarter;
37+
} as WorkspaceService;
3738
private userServiceMock: UserAuthentication = {
3839
blockUser: async (targetUserId: string, block: boolean): Promise<User> => {
3940
return {
@@ -45,7 +46,7 @@ export class APIUserServiceSpec {
4546
async before() {
4647
this.container = testContainer.createChild();
4748

48-
this.container.bind(WorkspaceStarter).toConstantValue(this.workspaceStarterMock);
49+
this.container.bind(WorkspaceService).toConstantValue(this.workspaceStarterMock);
4950
this.container.bind(UserAuthentication).toConstantValue(this.userServiceMock);
5051
this.container.bind(APIUserService).toSelf().inSingletonScope();
5152
}

components/server/src/api/user.ts

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@ import {
2525
} from "@gitpod/public-api/lib/gitpod/experimental/v1/user_pb";
2626
import { WorkspaceStarter } from "../workspace/workspace-starter";
2727
import { UserAuthentication } from "../user/user-authentication";
28-
import { validate } from "uuid";
29-
import { StopWorkspacePolicy } from "@gitpod/ws-manager/lib";
30-
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
28+
import { WorkspaceService } from "../workspace/workspace-service";
3129

3230
@injectable()
3331
export class APIUserService implements ServiceImpl<typeof UserServiceInterface> {
34-
@inject(WorkspaceStarter) protected readonly workspaceStarter: WorkspaceStarter;
32+
@inject(WorkspaceStarter) protected readonly workspaceService: WorkspaceService;
3533
@inject(UserAuthentication) protected readonly userService: UserAuthentication;
3634

3735
public async getAuthenticatedUser(req: GetAuthenticatedUserRequest): Promise<GetAuthenticatedUserResponse> {
@@ -59,39 +57,41 @@ export class APIUserService implements ServiceImpl<typeof UserServiceInterface>
5957
}
6058

6159
public async blockUser(req: BlockUserRequest): Promise<BlockUserResponse> {
62-
const { userId, reason } = req;
60+
throw new ConnectError("unimplemented", Code.Unimplemented);
61+
// TODO(gpl) Had to comment this out because of missing authentication info: Who is executing this?
62+
// const { userId, reason } = req;
6363

64-
if (!userId) {
65-
throw new ConnectError("userId is a required parameter", Code.InvalidArgument);
66-
}
67-
if (!validate(userId)) {
68-
throw new ConnectError("userId must be a valid uuid", Code.InvalidArgument);
69-
}
70-
if (!reason) {
71-
throw new ConnectError("reason is a required parameter", Code.InvalidArgument);
72-
}
64+
// if (!userId) {
65+
// throw new ConnectError("userId is a required parameter", Code.InvalidArgument);
66+
// }
67+
// if (!validate(userId)) {
68+
// throw new ConnectError("userId must be a valid uuid", Code.InvalidArgument);
69+
// }
70+
// if (!reason) {
71+
// throw new ConnectError("reason is a required parameter", Code.InvalidArgument);
72+
// }
7373

74-
// TODO: Once connect-node supports middlewares, lift the tracing into the middleware.
75-
const trace = {};
76-
await this.userService.blockUser(userId, true);
77-
log.info(`Blocked user ${userId}.`, {
78-
userId,
79-
reason,
80-
});
74+
// // TODO: Once connect-node supports middlewares, lift the tracing into the middleware.
75+
// const trace = {};
76+
// await this.userService.blockUser(userId, true);
77+
// log.info(`Blocked user ${userId}.`, {
78+
// userId,
79+
// reason,
80+
// });
8181

82-
const stoppedWorkspaces = await this.workspaceStarter.stopRunningWorkspacesForUser(
83-
trace,
84-
userId,
85-
reason,
86-
StopWorkspacePolicy.IMMEDIATELY,
87-
);
82+
// const stoppedWorkspaces = await this.workspaceService.stopRunningWorkspacesForUser(
83+
// trace,
84+
// userId,
85+
// reason,
86+
// StopWorkspacePolicy.IMMEDIATELY,
87+
// );
8888

89-
log.info(`Stopped ${stoppedWorkspaces.length} workspaces in response to BlockUser.`, {
90-
userId,
91-
reason,
92-
workspaceIds: stoppedWorkspaces.map((w) => w.id),
93-
});
89+
// log.info(`Stopped ${stoppedWorkspaces.length} workspaces in response to BlockUser.`, {
90+
// userId,
91+
// reason,
92+
// workspaceIds: stoppedWorkspaces.map((w) => w.id),
93+
// });
9494

95-
return new BlockUserResponse();
95+
// return new BlockUserResponse();
9696
}
9797
}

components/server/src/workspace/workspace-service.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ export class WorkspaceService {
9898
return workspace;
9999
}
100100

101+
private async doGetWorkspace(workspaceId: string, workspaceDB?: WorkspaceDB): Promise<Workspace> {
102+
const workspace = await (workspaceDB || this.db).findById(workspaceId);
103+
if (!workspace || !!workspace.softDeleted || workspace.deleted) {
104+
throw new ApplicationError(ErrorCodes.NOT_FOUND, "Workspace not found.");
105+
}
106+
return workspace;
107+
}
108+
101109
async getOwnerToken(userId: string, workspaceId: string): Promise<string> {
102110
await this.auth.checkPermissionOnWorkspace(userId, "access", workspaceId);
103111

@@ -131,6 +139,7 @@ export class WorkspaceService {
131139
});
132140
}
133141

142+
// stopWorkspace and related methods below
134143
async stopWorkspace(
135144
userId: string,
136145
workspaceId: string,
@@ -148,6 +157,29 @@ export class WorkspaceService {
148157
await this.workspaceStarter.stopWorkspaceInstance({}, instance.id, instance.region, reason, policy);
149158
}
150159

160+
public async stopRunningWorkspacesForUser(
161+
ctx: TraceContext,
162+
userId: string,
163+
userIdToStop: string,
164+
reason: string,
165+
policy?: StopWorkspacePolicy,
166+
): Promise<Workspace[]> {
167+
const infos = await this.db.findRunningInstancesWithWorkspaces(undefined, userIdToStop);
168+
await Promise.all(
169+
infos.map(async (info) => {
170+
await this.auth.checkPermissionOnWorkspace(userId, "stop", info.workspace.id);
171+
await this.workspaceStarter.stopWorkspaceInstance(
172+
ctx,
173+
info.latestInstance.id,
174+
info.latestInstance.region,
175+
reason,
176+
policy,
177+
);
178+
}),
179+
);
180+
return infos.map((instance) => instance.workspace);
181+
}
182+
151183
/**
152184
* This method does nothing beyond marking the given workspace as 'softDeleted' with the given cause and sets the 'softDeletedTime' to now.
153185
* The actual deletion happens as part of the regular workspace garbage collection.

components/server/src/workspace/workspace-starter.ts

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,11 @@ import {
9595
PortSpec,
9696
PortVisibility,
9797
StartWorkspaceRequest,
98-
StopWorkspacePolicy,
99-
StopWorkspaceRequest,
10098
WorkspaceMetadata,
10199
WorkspaceType,
102100
PortProtocol,
101+
StopWorkspacePolicy,
102+
StopWorkspaceRequest,
103103
} from "@gitpod/ws-manager/lib/core_pb";
104104
import * as grpc from "@grpc/grpc-js";
105105
import * as crypto from "crypto";
@@ -466,28 +466,6 @@ export class WorkspaceStarter {
466466
await client.stopWorkspace(ctx, req);
467467
}
468468

469-
public async stopRunningWorkspacesForUser(
470-
ctx: TraceContext,
471-
userID: string,
472-
reason: string,
473-
policy?: StopWorkspacePolicy,
474-
): Promise<Workspace[]> {
475-
const workspaceDb = this.workspaceDb.trace(ctx);
476-
const instances = await workspaceDb.findRunningInstancesWithWorkspaces(undefined, userID);
477-
await Promise.all(
478-
instances.map((instance) =>
479-
this.stopWorkspaceInstance(
480-
ctx,
481-
instance.latestInstance.id,
482-
instance.latestInstance.region,
483-
reason,
484-
policy,
485-
),
486-
),
487-
);
488-
return instances.map((instance) => instance.workspace);
489-
}
490-
491469
private async checkBlockedRepository(user: User, contextURL: string) {
492470
const blockedRepository = await this.blockedRepositoryDB.findBlockedRepositoryByURL(contextURL);
493471
if (!blockedRepository) return;

0 commit comments

Comments
 (0)