Skip to content

Commit dbbb66f

Browse files
committed
[public-api] Implement experimental TeamsService
1 parent 44ec8e5 commit dbbb66f

File tree

7 files changed

+214
-0
lines changed

7 files changed

+214
-0
lines changed

components/dashboard/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
"version": "0.0.0",
55
"private": true,
66
"dependencies": {
7+
"@bufbuild/connect-web": "^0.2.1",
78
"@gitpod/gitpod-protocol": "0.1.5",
9+
"@gitpod/public-api": "0.1.5",
810
"@stripe/react-stripe-js": "^1.7.2",
911
"@stripe/stripe-js": "^1.29.0",
1012
"configcat-js": "^6.0.0",

components/dashboard/src/projects/NewProject.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { trackEvent } from "../Analytics";
2121
import exclamation from "../images/exclamation.svg";
2222
import ErrorMessage from "../components/ErrorMessage";
2323
import Spinner from "../icons/Spinner.svg";
24+
import { teamsService } from "../service/public-api";
2425

2526
export default function NewProject() {
2627
const location = useLocation();
@@ -729,6 +730,26 @@ function NewTeam(props: { onSuccess: (team: Team) => void }) {
729730
if (!teamName) {
730731
return;
731732
}
733+
734+
try {
735+
const response = await teamsService.createTeam({
736+
name: teamName,
737+
});
738+
const team = response.team;
739+
setTeams(await getGitpodService().server.getTeams());
740+
741+
const mappedTeam: Team = {
742+
id: team?.id || "",
743+
name: team?.name || "",
744+
slug: team?.slug || "",
745+
creationTime: "",
746+
};
747+
props.onSuccess(mappedTeam);
748+
return;
749+
} catch (error) {
750+
console.error(error);
751+
}
752+
732753
try {
733754
const team = await getGitpodService().server.createTeam(teamName);
734755
setTeams(await getGitpodService().server.getTeams());
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Copyright (c) 2022 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 { createConnectTransport, createPromiseClient, Interceptor } from "@bufbuild/connect-web";
8+
9+
// Import service definition that you want to connect to.
10+
import { TeamService } from "@gitpod/public-api/lib/gitpod/experimental/v1/teams_connectweb";
11+
import { getGitpodService } from "./service";
12+
13+
let token: string | undefined;
14+
15+
const authInterceptor: Interceptor = (next) => async (req) => {
16+
if (!token) {
17+
const newToken = await getGitpodService().server.generateNewGitpodToken({
18+
type: 1,
19+
scopes: [
20+
"function:getGitpodTokenScopes",
21+
"function:getWorkspace",
22+
"function:getWorkspaces",
23+
"function:listenForWorkspaceInstanceUpdates",
24+
"resource:default",
25+
],
26+
});
27+
token = newToken;
28+
}
29+
30+
req.header.set("Authorization", `Bearer ${token}`);
31+
return await next(req);
32+
};
33+
34+
const transport = createConnectTransport({
35+
baseUrl: `${window.location.protocol}api.${window.location.host}`,
36+
interceptors: [authInterceptor],
37+
});
38+
39+
export const teamsService = createPromiseClient(TeamService, transport);

components/gitpod-protocol/go/gitpod-service.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ type APIInterface interface {
8181
TrackEvent(ctx context.Context, event *RemoteTrackMessage) (err error)
8282
GetSupportedWorkspaceClasses(ctx context.Context) (res []*SupportedWorkspaceClass, err error)
8383

84+
CreateTeam(ctx context.Context, params *CreateTeamParams) (*Team, error)
85+
GetTeamMembers(ctx context.Context, params *GetTeamMembersParams) ([]*TeamMemberInfo, error)
86+
8487
InstanceUpdates(ctx context.Context, instanceID string) (<-chan *WorkspaceInstance, error)
8588
}
8689

@@ -1379,6 +1382,30 @@ func (gp *APIoverJSONRPC) GetSupportedWorkspaceClasses(ctx context.Context) (res
13791382
return
13801383
}
13811384

1385+
func (gp *APIoverJSONRPC) CreateTeam(ctx context.Context, params *CreateTeamParams) (res *Team, err error) {
1386+
if gp == nil {
1387+
err = errNotConnected
1388+
return
1389+
}
1390+
var _params []interface{}
1391+
1392+
_params = append(_params, params)
1393+
err = gp.C.Call(ctx, "createTeam", _params, &res)
1394+
return
1395+
}
1396+
1397+
func (gp *APIoverJSONRPC) GetTeamMembers(ctx context.Context, params *GetTeamMembersParams) (res []*TeamMemberInfo, err error) {
1398+
if gp == nil {
1399+
err = errNotConnected
1400+
return
1401+
}
1402+
var _params []interface{}
1403+
1404+
_params = append(_params, params)
1405+
err = gp.C.Call(ctx, "getTeamMembers", _params, &res)
1406+
return
1407+
}
1408+
13821409
// PermissionName is the name of a permission
13831410
type PermissionName string
13841411

@@ -2071,3 +2098,34 @@ type UserMessage struct {
20712098
Title string `json:"title,omitempty"`
20722099
URL string `json:"url,omitempty"`
20732100
}
2101+
2102+
type CreateTeamParams struct {
2103+
Name string `json:"name,omitempty"`
2104+
}
2105+
2106+
type Team struct {
2107+
ID string `json:"id,omitempty"`
2108+
Name string `json:"name,omitempty"`
2109+
Slug string `json:"slug,omitempty"`
2110+
CreationTime string `json:"creationTime,omitempty"`
2111+
}
2112+
2113+
type GetTeamMembersParams struct {
2114+
TeamID string `json:"teamId,omitempty"`
2115+
}
2116+
2117+
type TeamMemberRole string
2118+
2119+
const (
2120+
TeamMember_Owner TeamMemberRole = "owner"
2121+
TeamMember_Member TeamMemberRole = "member"
2122+
)
2123+
2124+
type TeamMemberInfo struct {
2125+
UserId string `json:"userId,omitempty"`
2126+
FullName string `json:"fullName,omitempty"`
2127+
PrimaryEmail string `json:"primaryEmail,omitempty"`
2128+
AvatarUrl string `json:"avatarUrl,omitempty"`
2129+
Role TeamMemberRole `json:"role,omitempty"`
2130+
MemberSince string `json:"memberSince,omitempty"`
2131+
}

components/gitpod-protocol/go/mock.go

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License-AGPL.txt in the project root for license information.
4+
5+
package apiv1
6+
7+
import (
8+
"context"
9+
"fmt"
10+
11+
connect "github.com/bufbuild/connect-go"
12+
"github.com/gitpod-io/gitpod/common-go/log"
13+
protocol "github.com/gitpod-io/gitpod/gitpod-protocol"
14+
"github.com/gitpod-io/gitpod/public-api-server/pkg/auth"
15+
"github.com/gitpod-io/gitpod/public-api-server/pkg/proxy"
16+
v1 "github.com/gitpod-io/gitpod/public-api/experimental/v1"
17+
"github.com/gitpod-io/gitpod/public-api/experimental/v1/v1connect"
18+
)
19+
20+
func NewTeamsService(pool proxy.ServerConnectionPool) *TeamService {
21+
return &TeamService{
22+
connectionPool: pool,
23+
}
24+
}
25+
26+
var _ v1connect.TeamServiceHandler = (*TeamService)(nil)
27+
28+
type TeamService struct {
29+
connectionPool proxy.ServerConnectionPool
30+
31+
v1connect.UnimplementedTeamServiceHandler
32+
}
33+
34+
func (s *TeamService) CreateTeam(ctx context.Context, req *connect.Request[v1.CreateTeamRequest]) (*connect.Response[v1.CreateTeamResponse], error) {
35+
token := auth.TokenFromContext(ctx)
36+
37+
if req.Msg.GetName() == "" {
38+
return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("Name is a required argument when creating a team."))
39+
}
40+
41+
server, err := s.connectionPool.Get(ctx, token)
42+
if err != nil {
43+
log.Log.WithError(err).Error("Failed to get connection to server.")
44+
return nil, connect.NewError(connect.CodeInternal, err)
45+
}
46+
47+
team, err := server.CreateTeam(ctx, &protocol.CreateTeamParams{
48+
Name: req.Msg.GetName(),
49+
})
50+
if err != nil {
51+
return nil, proxy.ConvertError(err)
52+
}
53+
54+
return connect.NewResponse(&v1.CreateTeamResponse{
55+
Team: &v1.Team{
56+
Id: team.ID,
57+
Name: team.Name,
58+
Slug: team.Slug,
59+
},
60+
}), nil
61+
}

components/public-api-server/pkg/server/server.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ func register(srv *baseserver.Server, connPool proxy.ServerConnectionPool) error
9999
workspacesRoute, workspacesServiceHandler := v1connect.NewWorkspacesServiceHandler(apiv1.NewWorkspaceService(connPool), handlerOptions...)
100100
srv.HTTPMux().Handle(workspacesRoute, workspacesServiceHandler)
101101

102+
teamsRoute, teamsServiceHandler := v1connect.NewTeamServiceHandler(apiv1.NewTeamsService(connPool), handlerOptions...)
103+
srv.HTTPMux().Handle(teamsRoute, teamsServiceHandler)
104+
102105
return nil
103106
}
104107

0 commit comments

Comments
 (0)