Skip to content

Commit

Permalink
[server] implement getAuthenticatedUser RPC (#19187)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexTugarev authored Dec 8, 2023
1 parent da125ed commit 682878a
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 202 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
} from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb";
import {
Identity,
SetWorkspaceAutoStartOptionsRequest_WorkspaceAutostartOption,
User,
User_EmailNotificationSettings,
User_RoleOrPermission,
Expand Down Expand Up @@ -1290,8 +1291,10 @@ export class PublicAPIConverter {
});
}

fromWorkspaceAutostartOption(o: User_WorkspaceAutostartOption): WorkspaceAutostartOption {
const region = isWorkspaceRegion(o.region) ? o.region : "";
fromWorkspaceAutostartOption(
o: User_WorkspaceAutostartOption | SetWorkspaceAutoStartOptionsRequest_WorkspaceAutostartOption,
): WorkspaceAutostartOption {
const region = !!o.region && isWorkspaceRegion(o.region) ? o.region : "";
return {
cloneURL: o.cloneUrl,
ideSettings: this.fromEditorReference(o.editorSettings),
Expand Down
14 changes: 7 additions & 7 deletions components/server/src/api/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
import { HelloService } from "@gitpod/public-api/lib/gitpod/experimental/v1/dummy_connect";
import { StatsService } from "@gitpod/public-api/lib/gitpod/experimental/v1/stats_connect";
import { TeamsService as TeamsServiceDefinition } from "@gitpod/public-api/lib/gitpod/experimental/v1/teams_connect";
import { UserService as UserServiceDefinition } from "@gitpod/public-api/lib/gitpod/experimental/v1/user_connect";
import { OrganizationService } from "@gitpod/public-api/lib/gitpod/v1/organization_connect";
import { WorkspaceService } from "@gitpod/public-api/lib/gitpod/v1/workspace_connect";
import { UserService } from "@gitpod/public-api/lib/gitpod/v1/user_connect";
import { ConfigurationService } from "@gitpod/public-api/lib/gitpod/v1/configuration_connect";
import { AuthProviderService } from "@gitpod/public-api/lib/gitpod/v1/authprovider_connect";
import { EnvironmentVariableService } from "@gitpod/public-api/lib/gitpod/v1/envvar_connect";
Expand All @@ -31,7 +31,6 @@ import { isFgaChecksEnabled } from "../authorization/authorizer";
import { Config } from "../config";
import { grpcServerHandled, grpcServerHandling, grpcServerStarted } from "../prometheus-metrics";
import { SessionHandler } from "../session-handler";
import { UserService } from "../user/user-service";
import {
runWithSubjectId,
runWithRequestContext,
Expand All @@ -43,7 +42,6 @@ import { OrganizationServiceAPI } from "./organization-service-api";
import { RateLimited } from "./rate-limited";
import { APIStatsService as StatsServiceAPI } from "./stats";
import { APITeamsService as TeamsServiceAPI } from "./teams";
import { APIUserService as UserServiceAPI } from "./user";
import { WorkspaceServiceAPI } from "./workspace-service-api";
import { ConfigurationServiceAPI } from "./configuration-service-api";
import { AuthProviderServiceAPI } from "./auth-provider-service-api";
Expand All @@ -59,6 +57,8 @@ import { PrebuildServiceAPI } from "./prebuild-service-api";
import { PrebuildService } from "@gitpod/public-api/lib/gitpod/v1/prebuild_connect";
import { VerificationServiceAPI } from "./verification-service-api";
import { VerificationService } from "@gitpod/public-api/lib/gitpod/v1/verification_connect";
import { UserServiceAPI } from "./user-service-api";
import { UserService as UserServiceInternal } from "../user/user-service";

decorate(injectable(), PublicAPIConverter);

Expand All @@ -83,7 +83,7 @@ export class API {
@inject(PublicAPIConverter) private readonly apiConverter: PublicAPIConverter;
@inject(Redis) private readonly redis: Redis;
@inject(Config) private readonly config: Config;
@inject(UserService) private readonly userService: UserService;
@inject(UserServiceInternal) private readonly userServiceInternal: UserServiceInternal;
@inject(BearerAuth) private readonly bearerAuthenticator: BearerAuth;
@inject(PrebuildServiceAPI) private readonly prebuildServiceApi: PrebuildServiceAPI;
@inject(VerificationServiceAPI) private readonly verificationServiceApi: VerificationServiceAPI;
Expand Down Expand Up @@ -114,7 +114,6 @@ export class API {
app.use(
expressConnectMiddleware({
routes: (router: ConnectRouter) => {
router.service(UserServiceDefinition, this.userServiceApi);
router.service(TeamsServiceDefinition, this.teamServiceApi);
router.service(StatsService, this.tatsServiceApi);
},
Expand All @@ -128,6 +127,7 @@ export class API {
routes: (router: ConnectRouter) => {
for (const [type, impl] of [
service(HelloService, this.helloServiceApi),
service(UserService, this.userServiceApi),
service(WorkspaceService, this.workspaceServiceApi),
service(OrganizationService, this.organizationServiceApi),
service(ConfigurationService, this.configurationServiceApi),
Expand All @@ -143,7 +143,7 @@ export class API {
},
}),
);
// TODO(al) cover unhandled cases
// TODO(ak) cover unhandled cases
}

/**
Expand Down Expand Up @@ -346,7 +346,7 @@ export class API {
if (subjectId.kind === "user") {
const userId = subjectId.userId()!;
try {
await this.userService.findUserById(userId, userId);
await this.userServiceInternal.findUserById(userId, userId);
} catch (e) {
if (e instanceof ApplicationError && e.code === ErrorCodes.NOT_FOUND) {
throw new ConnectError("unauthorized", Code.PermissionDenied);
Expand Down
72 changes: 72 additions & 0 deletions components/server/src/api/user-service-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Copyright (c) 2023 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 { HandlerContext, ServiceImpl } from "@connectrpc/connect";
import { UserService as UserServiceInterface } from "@gitpod/public-api/lib/gitpod/v1/user_connect";
import { inject, injectable } from "inversify";
import { PublicAPIConverter } from "@gitpod/public-api-common/lib/public-api-converter";
import {
UpdateUserRequest,
UpdateUserResponse,
GetAuthenticatedUserRequest,
GetAuthenticatedUserResponse,
SetWorkspaceAutoStartOptionsRequest,
SetWorkspaceAutoStartOptionsResponse,
} from "@gitpod/public-api/lib/gitpod/v1/user_pb";
import { UserService } from "../user/user-service";
import { validate as uuidValidate } from "uuid";
import { ctxUserId } from "../util/request-context";
import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";

@injectable()
export class UserServiceAPI implements ServiceImpl<typeof UserServiceInterface> {
constructor(
@inject(PublicAPIConverter) private readonly converter: PublicAPIConverter,
@inject(UserService) private readonly userService: UserService,
) {}

async getAuthenticatedUser(
request: GetAuthenticatedUserRequest,
_: HandlerContext,
): Promise<GetAuthenticatedUserResponse> {
const userId = ctxUserId();
const user = await this.userService.findUserById(userId, userId);
return new GetAuthenticatedUserResponse({
user: this.converter.toUser(user),
});
}

async updateUser(request: UpdateUserRequest, _: HandlerContext): Promise<UpdateUserResponse> {
throw new ApplicationError(ErrorCodes.UNIMPLEMENTED, "not implemented");
}

async setWorkspaceAutoStartOptions(
request: SetWorkspaceAutoStartOptionsRequest,
_: HandlerContext,
): Promise<SetWorkspaceAutoStartOptionsResponse> {
const userId = ctxUserId();

const { userId: requestUserId, workspaceAutostartOptions } = request;

if (!uuidValidate(requestUserId) || !workspaceAutostartOptions) {
throw new ApplicationError(ErrorCodes.BAD_REQUEST, "userId and workspaceAutostartOptions are required");
}

const newWorkspaceAutostartOptions = workspaceAutostartOptions.map((o) =>
this.converter.fromWorkspaceAutostartOption(o),
);
const currentUser = await this.userService.findUserById(userId, requestUserId);
await this.userService.updateUser(userId, {
id: currentUser.id,
additionalData: {
...currentUser.additionalData,
workspaceAutostartOptions: newWorkspaceAutostartOptions,
},
});

return new SetWorkspaceAutoStartOptionsResponse();
}
}
80 changes: 0 additions & 80 deletions components/server/src/api/user.spec.ts

This file was deleted.

113 changes: 0 additions & 113 deletions components/server/src/api/user.ts

This file was deleted.

0 comments on commit 682878a

Please sign in to comment.