Skip to content

Commit 682878a

Browse files
authored
[server] implement getAuthenticatedUser RPC (#19187)
1 parent da125ed commit 682878a

File tree

5 files changed

+84
-202
lines changed

5 files changed

+84
-202
lines changed

components/public-api/typescript-common/src/public-api-converter.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
} from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb";
3030
import {
3131
Identity,
32+
SetWorkspaceAutoStartOptionsRequest_WorkspaceAutostartOption,
3233
User,
3334
User_EmailNotificationSettings,
3435
User_RoleOrPermission,
@@ -1290,8 +1291,10 @@ export class PublicAPIConverter {
12901291
});
12911292
}
12921293

1293-
fromWorkspaceAutostartOption(o: User_WorkspaceAutostartOption): WorkspaceAutostartOption {
1294-
const region = isWorkspaceRegion(o.region) ? o.region : "";
1294+
fromWorkspaceAutostartOption(
1295+
o: User_WorkspaceAutostartOption | SetWorkspaceAutoStartOptionsRequest_WorkspaceAutostartOption,
1296+
): WorkspaceAutostartOption {
1297+
const region = !!o.region && isWorkspaceRegion(o.region) ? o.region : "";
12951298
return {
12961299
cloneURL: o.cloneUrl,
12971300
ideSettings: this.fromEditorReference(o.editorSettings),

components/server/src/api/server.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
1313
import { HelloService } from "@gitpod/public-api/lib/gitpod/experimental/v1/dummy_connect";
1414
import { StatsService } from "@gitpod/public-api/lib/gitpod/experimental/v1/stats_connect";
1515
import { TeamsService as TeamsServiceDefinition } from "@gitpod/public-api/lib/gitpod/experimental/v1/teams_connect";
16-
import { UserService as UserServiceDefinition } from "@gitpod/public-api/lib/gitpod/experimental/v1/user_connect";
1716
import { OrganizationService } from "@gitpod/public-api/lib/gitpod/v1/organization_connect";
1817
import { WorkspaceService } from "@gitpod/public-api/lib/gitpod/v1/workspace_connect";
18+
import { UserService } from "@gitpod/public-api/lib/gitpod/v1/user_connect";
1919
import { ConfigurationService } from "@gitpod/public-api/lib/gitpod/v1/configuration_connect";
2020
import { AuthProviderService } from "@gitpod/public-api/lib/gitpod/v1/authprovider_connect";
2121
import { EnvironmentVariableService } from "@gitpod/public-api/lib/gitpod/v1/envvar_connect";
@@ -31,7 +31,6 @@ import { isFgaChecksEnabled } from "../authorization/authorizer";
3131
import { Config } from "../config";
3232
import { grpcServerHandled, grpcServerHandling, grpcServerStarted } from "../prometheus-metrics";
3333
import { SessionHandler } from "../session-handler";
34-
import { UserService } from "../user/user-service";
3534
import {
3635
runWithSubjectId,
3736
runWithRequestContext,
@@ -43,7 +42,6 @@ import { OrganizationServiceAPI } from "./organization-service-api";
4342
import { RateLimited } from "./rate-limited";
4443
import { APIStatsService as StatsServiceAPI } from "./stats";
4544
import { APITeamsService as TeamsServiceAPI } from "./teams";
46-
import { APIUserService as UserServiceAPI } from "./user";
4745
import { WorkspaceServiceAPI } from "./workspace-service-api";
4846
import { ConfigurationServiceAPI } from "./configuration-service-api";
4947
import { AuthProviderServiceAPI } from "./auth-provider-service-api";
@@ -59,6 +57,8 @@ import { PrebuildServiceAPI } from "./prebuild-service-api";
5957
import { PrebuildService } from "@gitpod/public-api/lib/gitpod/v1/prebuild_connect";
6058
import { VerificationServiceAPI } from "./verification-service-api";
6159
import { VerificationService } from "@gitpod/public-api/lib/gitpod/v1/verification_connect";
60+
import { UserServiceAPI } from "./user-service-api";
61+
import { UserService as UserServiceInternal } from "../user/user-service";
6262

6363
decorate(injectable(), PublicAPIConverter);
6464

@@ -83,7 +83,7 @@ export class API {
8383
@inject(PublicAPIConverter) private readonly apiConverter: PublicAPIConverter;
8484
@inject(Redis) private readonly redis: Redis;
8585
@inject(Config) private readonly config: Config;
86-
@inject(UserService) private readonly userService: UserService;
86+
@inject(UserServiceInternal) private readonly userServiceInternal: UserServiceInternal;
8787
@inject(BearerAuth) private readonly bearerAuthenticator: BearerAuth;
8888
@inject(PrebuildServiceAPI) private readonly prebuildServiceApi: PrebuildServiceAPI;
8989
@inject(VerificationServiceAPI) private readonly verificationServiceApi: VerificationServiceAPI;
@@ -114,7 +114,6 @@ export class API {
114114
app.use(
115115
expressConnectMiddleware({
116116
routes: (router: ConnectRouter) => {
117-
router.service(UserServiceDefinition, this.userServiceApi);
118117
router.service(TeamsServiceDefinition, this.teamServiceApi);
119118
router.service(StatsService, this.tatsServiceApi);
120119
},
@@ -128,6 +127,7 @@ export class API {
128127
routes: (router: ConnectRouter) => {
129128
for (const [type, impl] of [
130129
service(HelloService, this.helloServiceApi),
130+
service(UserService, this.userServiceApi),
131131
service(WorkspaceService, this.workspaceServiceApi),
132132
service(OrganizationService, this.organizationServiceApi),
133133
service(ConfigurationService, this.configurationServiceApi),
@@ -143,7 +143,7 @@ export class API {
143143
},
144144
}),
145145
);
146-
// TODO(al) cover unhandled cases
146+
// TODO(ak) cover unhandled cases
147147
}
148148

149149
/**
@@ -346,7 +346,7 @@ export class API {
346346
if (subjectId.kind === "user") {
347347
const userId = subjectId.userId()!;
348348
try {
349-
await this.userService.findUserById(userId, userId);
349+
await this.userServiceInternal.findUserById(userId, userId);
350350
} catch (e) {
351351
if (e instanceof ApplicationError && e.code === ErrorCodes.NOT_FOUND) {
352352
throw new ConnectError("unauthorized", Code.PermissionDenied);
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* Copyright (c) 2023 Gitpod GmbH. All rights reserved.
3+
* Licensed under the GNU Affero General Public License (AGPL).
4+
* See License.AGPL.txt in the project root for license information.
5+
*/
6+
7+
import { HandlerContext, ServiceImpl } from "@connectrpc/connect";
8+
import { UserService as UserServiceInterface } from "@gitpod/public-api/lib/gitpod/v1/user_connect";
9+
import { inject, injectable } from "inversify";
10+
import { PublicAPIConverter } from "@gitpod/public-api-common/lib/public-api-converter";
11+
import {
12+
UpdateUserRequest,
13+
UpdateUserResponse,
14+
GetAuthenticatedUserRequest,
15+
GetAuthenticatedUserResponse,
16+
SetWorkspaceAutoStartOptionsRequest,
17+
SetWorkspaceAutoStartOptionsResponse,
18+
} from "@gitpod/public-api/lib/gitpod/v1/user_pb";
19+
import { UserService } from "../user/user-service";
20+
import { validate as uuidValidate } from "uuid";
21+
import { ctxUserId } from "../util/request-context";
22+
import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
23+
24+
@injectable()
25+
export class UserServiceAPI implements ServiceImpl<typeof UserServiceInterface> {
26+
constructor(
27+
@inject(PublicAPIConverter) private readonly converter: PublicAPIConverter,
28+
@inject(UserService) private readonly userService: UserService,
29+
) {}
30+
31+
async getAuthenticatedUser(
32+
request: GetAuthenticatedUserRequest,
33+
_: HandlerContext,
34+
): Promise<GetAuthenticatedUserResponse> {
35+
const userId = ctxUserId();
36+
const user = await this.userService.findUserById(userId, userId);
37+
return new GetAuthenticatedUserResponse({
38+
user: this.converter.toUser(user),
39+
});
40+
}
41+
42+
async updateUser(request: UpdateUserRequest, _: HandlerContext): Promise<UpdateUserResponse> {
43+
throw new ApplicationError(ErrorCodes.UNIMPLEMENTED, "not implemented");
44+
}
45+
46+
async setWorkspaceAutoStartOptions(
47+
request: SetWorkspaceAutoStartOptionsRequest,
48+
_: HandlerContext,
49+
): Promise<SetWorkspaceAutoStartOptionsResponse> {
50+
const userId = ctxUserId();
51+
52+
const { userId: requestUserId, workspaceAutostartOptions } = request;
53+
54+
if (!uuidValidate(requestUserId) || !workspaceAutostartOptions) {
55+
throw new ApplicationError(ErrorCodes.BAD_REQUEST, "userId and workspaceAutostartOptions are required");
56+
}
57+
58+
const newWorkspaceAutostartOptions = workspaceAutostartOptions.map((o) =>
59+
this.converter.fromWorkspaceAutostartOption(o),
60+
);
61+
const currentUser = await this.userService.findUserById(userId, requestUserId);
62+
await this.userService.updateUser(userId, {
63+
id: currentUser.id,
64+
additionalData: {
65+
...currentUser.additionalData,
66+
workspaceAutostartOptions: newWorkspaceAutostartOptions,
67+
},
68+
});
69+
70+
return new SetWorkspaceAutoStartOptionsResponse();
71+
}
72+
}

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

Lines changed: 0 additions & 80 deletions
This file was deleted.

components/server/src/api/user.ts

Lines changed: 0 additions & 113 deletions
This file was deleted.

0 commit comments

Comments
 (0)