Skip to content

Commit 71643c8

Browse files
committed
[server] Implement grpc/connect getTeam RPC
1 parent 8b9fee9 commit 71643c8

File tree

4 files changed

+59
-10
lines changed

4 files changed

+59
-10
lines changed

components/gitpod-db/src/team-db.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export interface TeamDB {
3535
setTeamMemberSubscription(userId: string, teamId: string, subscriptionId: string): Promise<void>;
3636
removeMemberFromTeam(userId: string, teamId: string): Promise<void>;
3737
findTeamMembershipInviteById(inviteId: string): Promise<TeamMembershipInvite>;
38-
findGenericInviteByTeamId(teamId: string): Promise<TeamMembershipInvite | undefined>;
38+
findGenericInviteByTeamId(teamId: string): Promise<TeamMembershipInvite>;
3939
resetGenericInvite(teamId: string): Promise<TeamMembershipInvite>;
4040
deleteTeam(teamId: string): Promise<void>;
4141

components/gitpod-db/src/typeorm/team-db-impl.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,15 @@ export class TeamDBImpl implements TeamDB {
337337
return invite;
338338
}
339339

340-
public async findGenericInviteByTeamId(teamId: string): Promise<TeamMembershipInvite | undefined> {
340+
public async findGenericInviteByTeamId(teamId: string): Promise<TeamMembershipInvite> {
341341
const inviteRepo = await this.getMembershipInviteRepo();
342342
const all = await inviteRepo.find({ teamId });
343-
return all.filter((i) => i.invalidationTime === "" && !i.invitedEmail)[0];
343+
const invite = all.filter((i) => i.invalidationTime === "" && !i.invitedEmail)[0];
344+
if (!invite) {
345+
return this.resetGenericInvite(teamId);
346+
}
347+
348+
return invite;
344349
}
345350

346351
public async resetGenericInvite(teamId: string): Promise<TeamMembershipInvite> {

components/server/src/api/teams.ts

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
import { Code, ConnectError, ServiceImpl } from "@bufbuild/connect";
8-
import { injectable } from "inversify";
8+
import { inject, injectable } from "inversify";
99
import { TeamsService as TeamServiceInterface } from "@gitpod/public-api/lib/gitpod/experimental/v1/teams_connectweb";
1010
import {
1111
CreateTeamRequest,
@@ -22,17 +22,43 @@ import {
2222
ListTeamsResponse,
2323
ResetTeamInvitationRequest,
2424
ResetTeamInvitationResponse,
25+
Team,
26+
TeamInvitation,
27+
TeamMember,
28+
TeamRole,
2529
UpdateTeamMemberRequest,
2630
UpdateTeamMemberResponse,
2731
} from "@gitpod/public-api/lib/gitpod/experimental/v1/teams_pb";
32+
import { TeamDB } from "@gitpod/gitpod-db/lib";
33+
import { validate } from "uuid";
34+
import { OrgMemberInfo, Organization, TeamMembershipInvite } from "@gitpod/gitpod-protocol";
35+
import { Timestamp } from "@bufbuild/protobuf";
2836

2937
@injectable()
3038
export class APITeamService implements ServiceImpl<typeof TeamServiceInterface> {
39+
@inject(TeamDB) protected readonly teamDB: TeamDB;
40+
3141
public async createTeam(req: CreateTeamRequest): Promise<CreateTeamResponse> {
3242
throw new ConnectError("unimplemented", Code.Unimplemented);
3343
}
3444
public async getTeam(req: GetTeamRequest): Promise<GetTeamResponse> {
35-
throw new ConnectError("unimplemented", Code.Unimplemented);
45+
const { teamId } = req;
46+
47+
if (!teamId || !validate(teamId)) {
48+
throw new ConnectError("Invalid argument: teamId", Code.InvalidArgument);
49+
}
50+
51+
const team = await this.teamDB.findTeamById(teamId);
52+
if (!team) {
53+
throw new ConnectError(`Team (ID: ${teamId}) does not exist`, Code.NotFound);
54+
}
55+
56+
const members = await this.teamDB.findMembersByTeam(teamId);
57+
let invite = await this.teamDB.findGenericInviteByTeamId(teamId);
58+
59+
return new GetTeamResponse({
60+
team: toAPITeam(team, members, invite),
61+
});
3662
}
3763
public async listTeams(req: ListTeamsRequest): Promise<ListTeamsResponse> {
3864
throw new ConnectError("unimplemented", Code.Unimplemented);
@@ -53,3 +79,25 @@ export class APITeamService implements ServiceImpl<typeof TeamServiceInterface>
5379
throw new ConnectError("unimplemented", Code.Unimplemented);
5480
}
5581
}
82+
83+
function toAPITeam(team: Organization, members: OrgMemberInfo[], invite: TeamMembershipInvite): Team {
84+
return new Team({
85+
id: team.id,
86+
name: team.name,
87+
slug: team.slug,
88+
teamInvitation: new TeamInvitation({
89+
id: invite.id,
90+
}),
91+
members: members.map(
92+
(m) =>
93+
new TeamMember({
94+
avatarUrl: m.avatarUrl,
95+
fullName: m.fullName,
96+
memberSince: Timestamp.fromDate(new Date(m.memberSince)),
97+
primaryEmail: m.primaryEmail,
98+
role: m.role === "owner" ? TeamRole.OWNER : TeamRole.MEMBER,
99+
userId: m.userId,
100+
}),
101+
),
102+
});
103+
}

components/server/src/workspace/gitpod-server-impl.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,11 +2390,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
23902390
this.checkUser("getGenericInvite");
23912391
await this.guardTeamOperation(teamId, "get", "org_members_write");
23922392

2393-
const invite = await this.teamDB.findGenericInviteByTeamId(teamId);
2394-
if (invite) {
2395-
return invite;
2396-
}
2397-
return this.teamDB.resetGenericInvite(teamId);
2393+
return await this.teamDB.findGenericInviteByTeamId(teamId);
23982394
}
23992395

24002396
public async resetGenericInvite(ctx: TraceContext, teamId: string): Promise<TeamMembershipInvite> {

0 commit comments

Comments
 (0)